首页 > 解决方案 > lisp中的字符串加法赋值

问题描述

我有一个带有条件的循环,根据该条件我决定是否应该将某些内容附加到现有字符串。在 Python 中,它应该看起来像(这是虚拟代码,只是为了展示这个想法):

result_str = ''
for item in range(5):
  if item % 2 == 0:
    result_str += str(item)

print(result_str)

输出:024

所以问题是:如何+=在 lisp 中对字符串 () 执行加法赋值?

标签: lispcommon-lisp

解决方案


字符串连接依赖于更通用的CONCATENATE函数:

(concatenate 'string "a" "b")
=> "ab"

由于某些人认为它很冗长,因此您可以找到实现较短版本的库:

(ql:quickload :rutils)
(import 'rutils:strcat)

进而:

(strcat "a" "b")

为了分配和增长字符串,您需要使用SETF现有变量。

(let ((string ""))
  (dotimes (i 5)
    (when (evenp i)
      (setf string (strcat string (princ-to-string i)))))
  string)

Lisp 中更惯用的方法是避免字符串连接,而是在写入缓冲区的流中打印。

(with-output-to-string (stream)
  ;; now, stream is bound to an output stream 
  ;; that writes into a string. The whole form 
  ;; returns that string.
  (loop
     for i from 0 below 5 by 2
     do (princ i stream)))
 => "024"

上面,stream只是用于命名流的符号,您可以使用任何其他符号,包括*standard-output*表示当前输出流的特殊变量。这样做会使封闭的代码将其标准输出重定向到字符串流。

构建中间列表的另一种方法如下,其中iotaalexandria库中的一个小实用程序:

(delete-if #'oddp (alexandria:iota 5))
=> (0 2 4)

为了生成字符串,您还可以使用FORMAT,它有一个可以迭代列表的指令:

(format nil "~{~a~}" '(0 2 4))
=> "024"

nil目的地代表一个字符串目的地,意思是(format nil ...)返回一个字符串。每个指令都以波浪号 ( ~) 开头,~{~}包含一个迭代指令;在该块内,~a“美观地”打印值(不可读)。


推荐阅读