循环作为表达
与今天使用的几乎所有其他编程语言中的循环不同,Common Lisp 中的 LOOP
可以用作表达式:
(let ((doubled (loop for x from 1 to 10
collect (* 2 x))))
doubled) ;; ==> (2 4 6 8 10 12 14 16 18 20)
(loop for x from 1 to 10 sum x)
MAXIMIZE
使 LOOP
返回已评估的最大值。MINIMIZE
与 MAXIMIZE
相反。
(loop repeat 100
for x = (random 1000)
maximize x)
COUNT
告诉你在循环期间表达式计算到非 NIL
的次数:
(loop repeat 100
for x = (random 1000)
count (evenp x))
LOOP
还具有 some
,every
和 notany
功能的等价物:
(loop for ch across "foobar"
thereis (eq ch #\a))
(loop for x in '(a b c d e f 1)
always (symbolp x))
(loop for x in '(1 3 5 7)
never (evenp x))
…除了它们不限于迭代序列:
(loop for value = (read *standard-input* nil :eof)
until (eq value :eof)
never (stringp value))
LOOP
值生成动词也可以用 -ing 后缀编写:
(loop repeat 100
for x = (random 1000)
minimizing x)
也可以将这些动词生成的值捕获到变量(由 LOOP
宏隐式创建)中,这样你就可以一次生成多个值:
(loop repeat 100
for x = (random 1000)
maximizing x into biggest
minimizing x into smallest
summing x into total
collecting x into xs
finally (return (values biggest smallest total xs)))
你可以拥有多个 collect
,count
等子句,它们会收集到相同的输出值。它们将按顺序执行。
以下内容将关联列表(可以与 assoc
一起使用)转换为属性列表(可以与 getf
一起使用):
(loop for (key . value) in assoc-list
collect key
collect value)
虽然这是更好的风格:
(loop for (key . value) in assoc-list
append (list key value))