2011-06-01 40 views
3

我正在尝试创建一个函数zip(注意这不是家庭作业),它同时遍历多个列表,将函数应用于每个元素列表,如下所示:在Common Lisp中一起压缩列表 - Problem with“and”

(zip f '(1 2 3) '(4 5 6) '(7 8 9)) = (list (f 1 4 7) (f 2 5 8) (f 3 6 9)) 
(zip f '(1 2 3 4) '(5 6) '(7 8 9)) = (list (f 1 5 7) (f 2 6 8)) 

基本上,当任何列表中的元素用完时,它会停止。这是我当前的尝试:

(defun zip (f &rest lists) 
    (if (apply and lists) ; <- Here is where I think the problem is. 
    (cons (apply f (mapcar #'car lists)) (zip f &rest (mapcar #'cdr lists))) 
    nil)) 

我想知道如何解决的条件语句与and,或诸如此类的话上班。我认为问题出现在and是一个宏。我也想知道是否有一个内置函数来做到这一点。

回答

13

你重新实现mapcar

? (mapcar #'list '(1 2 3) '(4 5 6) '(7 8 9)) 
((1 4 7) (2 5 8) (3 6 9)) 
? (mapcar #'list '(1 2 3 4) '(5 6) '(7 8 9)) 
((1 5 7) (2 6 8)) 
? (mapcar #'+ '(1 2 3) '(4 5 6) '(7 8 9)) 
(12 15 18) 
? (mapcar #'+ '(1 2 3 4) '(5 6) '(7 8 9)) 
(13 16) 

顺便说一句,你在地方的all代码想要的功能是and

+0

谢谢!我不知道'mapcar'可以做到这一点! – Tom 2011-06-01 03:04:44

+0

'全部'是偶然的。现在我能做些什么来解决这个问题? – Tom 2011-06-01 03:13:01

+0

(apply#'and lists) ;并从第二个参数中删除&休息,以保留 – 2011-06-01 03:21:16

0

您可以使用pairlis

> (pairlis '(1 2 3 4) '(a b c d)) 

((4 . D) (3 . C) (2 . B) (1 . A)) 

> (let ((alist '((hello . world) (foo . bar)))) 
    (pairlis '(1 2) '(a b) alist)) 

((2 . B) (1 . A) (HELLO . WORLD) (FOO . BAR)) 

clhs: pairlis

编辑: 对不起。我现在看到我没有回答这个问题。