2011-12-15 46 views
3

我一直在使用Clojure玩弄,并决定将结合会员名:mapcat和列表来模拟这种行为高阶函数:传递的变量列表中逐个到Clojure的功能

Clojure> (mapcat list '(1 2 3 4) '(5 6 7 8)) 
(1 5 2 6 3 7 4 8) 

我第一次尝试定义mapcatList如下:

Clojure> (defn mapcatList[& more](mapcat list more)) 
#'sandbox99/mapcatList 
Clojure> (mapcatList '(1 2 3 4) '(5 6 7 8)) 
((1 2 3 4) (5 6 7 8)) 

显然函数不表现我怎么会喜欢它,我觉得这是因为两个列表都被放进一个列表,并通过作为一个参数,而不是两个。 我可以用下面的亡羊补牢,

Clojure> (defn mapcatList[x y & more](mapcat list x y)) 
#'sandbox99/mapcatList 
Clojure> (mapcatList '(1 2 3 4) '(5 6 7 8)) 
(1 5 2 6 3 7 4 8) 

该解决方案具有两个列表效果很好,但我想在功能与参数的数量可变的工作。

我的问题:如何将一个可变数量的参数传递给一个函数,然后将它们解构为使它们作为单独的参数一起传递给'mapcat list'?

+0

(defn mapcatList [&more](apply mapcat list more)) – vedang 2011-12-15 16:50:45

回答

13

您正在寻找apply。这用一个序列中提供的参数调用一个函数。

但是你是否知道有一个函数interleave,它正是你的mapcatList所要做的?

+0

是的,我是。这整个事情开始后,我试图实现交错我自己。谢谢。 – wespiserA 2011-12-15 17:36:02

5

你是对的,由于vararg声明,参数被包装在一个列表中。您需要apply的参数,以解开的参数列表:

(defn mapcatList[& more] 
    (apply mapcat list more)) 

user=> (mapcatList '(1 2 3 4) '(5 6 7 8))    
(1 5 2 6 3 7 4 8) 
user=> (mapcatList '(1 2 3 4) '(5 6 7 8) '(\a \b \c \d)) 
(1 5 \a 2 6 \b 3 7 \c 4 8 \d)