Loops 如何在Common Lisp中与'loop'宏一起使用依赖循环变量
考虑下面的Loops 如何在Common Lisp中与'loop'宏一起使用依赖循环变量,loops,common-lisp,Loops,Common Lisp,考虑下面的C代码片段;M的实际值 而且arr的内容实际上并不重要 int arr[M] = {...}; for (int i=0; i<M; ++i) { for (int j=i+1; j<M; ++j) { /* do something */ } } 但这似乎相当笨重 请注意,其他类似的处理范围不是列表。不确定您实际想要计算什么,但我认为它并不笨重 例如: CL-USER 6 > (loop for (head . tail) on
C
代码片段;M的实际值
而且arr
的内容实际上并不重要
int arr[M] = {...};
for (int i=0; i<M; ++i) {
for (int j=i+1; j<M; ++j) {
/* do something */
}
}
但这似乎相当笨重
请注意,其他类似的处理范围不是列表。不确定您实际想要计算什么,但我认为它并不笨重
例如:
CL-USER 6 > (loop for (head . tail) on '(1 2 3 4)
do (loop for item in tail
do (print (list head item))))
(1 2)
(1 3)
(1 4)
(2 3)
(2 4)
(3 4)
NIL
如果要根据某些测试保留配对:
CL-USER 36 > (defun mapcan-pairs (fn list)
(loop for (head . tail) on list
nconc (loop for item in tail
nconc (funcall fn head item))))
MAPCAN-PAIRS
CL-USER 37 > (defun keep-pairs (test list)
(mapcan-pairs (lambda (a b)
(when (funcall test a b)
(list (cons a b))))
list))
KEEP-PAIRS
CL-USER 38 > (keep-pairs (lambda (a b)
(= 13 (+ a b)))
'(1 2 3 7 1 4 5 6 3 5 10 15 3))
((3 . 10) (7 . 6) (3 . 10) (10 . 3))
很快,谢谢雷纳·乔斯维格。解构看起来当然比使用cdr
更好。关于我实际想要计算的内容:假设列表中的元素有一些条件(例如,总和等于42)。我想在列表中找到满足条件的所有值对。@Aroob-like(循环:for(head.tail):on-list:ncoc(循环:for-item:in-tail:if(=target(+head-item)):collect(list-head-item))
?@sylvester-Yes,像这样;RainerJoswig已经将此纳入了他的回答中。我想我真正想要的是列表理解。但就目前而言,这符合我的目的。@Sylvester现在我看得更仔细了,你的内部循环中有一个collect
关键字,而RainerJoswig在内部循环中使用ncoc
。为什么?@Aroob:因为他在内部循环中有IF,而我的函数更一般,WHEN在外部。您可以使用NCOC变量作为更通用的构建块,通过我的MAPCAN-PAIRS、KEEP-PAIRS函数演示。
CL-USER 36 > (defun mapcan-pairs (fn list)
(loop for (head . tail) on list
nconc (loop for item in tail
nconc (funcall fn head item))))
MAPCAN-PAIRS
CL-USER 37 > (defun keep-pairs (test list)
(mapcan-pairs (lambda (a b)
(when (funcall test a b)
(list (cons a b))))
list))
KEEP-PAIRS
CL-USER 38 > (keep-pairs (lambda (a b)
(= 13 (+ a b)))
'(1 2 3 7 1 4 5 6 3 5 10 15 3))
((3 . 10) (7 . 6) (3 . 10) (10 . 3))