如何在Common Lisp中使用带有`loop`宏的依赖循环变量

时间:2017-12-10 21:52:46

标签: 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 */
    }
}

使用loop宏(或loop不是正确的工具,任何其他构造)的(惯用的和有效的)Common Lisp模拟是什么?

我知道比较数组访问和列表访问是不正确的,但无法提供更好的示例。

我尝试过的一种可能性如下:

(defvar l '(1 2 ...))

(loop :for n :on l :do
   (loop :for x :in (cdr n) :do
      ;; do something
      ))

但这似乎相当笨重。

请注意,其他类似的questions处理的范围不是列表。

1 个答案:

答案 0 :(得分:2)

不确定你真正想要计算什么,但我认为它不是很笨重。

示例:

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))