2012-01-30 54 views
1

我正在寻找一种简洁的方式来映射跨越多个列表的可变参数函数,但不是像MAPCAR那样将列表作为单独的参数传递,而是要传递由任意数量的列表组成的单个列表,并映射通过包含的列表名单。我事先不知道列表中有多少个列表,所以我不能解构它。如何简洁地映射列表清单?

我尝试过将MAPCAR和APPLY以各种方式组合起来,但无法弄清楚。我必须放弃使用MAP并明确写入迭代吗?

这里是一个函数,做什么,我想:

(defun map-within (fn list-of-lists &optional(maptype #'mapcar)) 
    "Map FN on the lists contained in LIST-OF-LISTS" 
    (cond ((null list-of-lists) nil) 
    ((null (cdr list-of-lists)) (car list-of-lists)) 
    (t 
    (funcall maptype fn 
     (car list-of-lists) 
     (map-within fn (cdr list-of-lists) maptype))))) 

其中

(map-within #'+ '((1 2 3) (10 20 30) (100 200 300))) => (111 222 333) 

有没有从地图制成的拉姆达,可以只用一行表示这个的一些神奇的应用程序?

回答

4

您可以使用apply这样的:

(apply #'mapcar #'+ '((1 2 3) (10 20 30) (100 200 300))) 
=> (111 222 333) 
+0

谢谢,这是少了很多神奇的比我的预期,显然它没有发生,我只是尝试一下。我有一个概念,APPLY带了两个参数,一个函数和一个列表,并且将列表元素的函数作为参数调用,实际上它会在剩下的参数上调用函数,而特别处理最后一个参数。 – 2012-01-30 12:04:03

+0

@PaulRichter:是的,你应该看看['list *'](http://www.lispworks.com/documentation/HyperSpec/Body/f_list_.htm)。 – Daimrod 2012-01-30 12:17:59

+1

可能只适用于CALL-ARGUMENTS-LIMIT列表,因为解决方案使用APPLY – 2012-01-30 22:24:29