4

我一直在玩clojure,并决定制作一个结合了mapcat和list的高阶函数来模拟这种行为:

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 列表”?

4

2 回答 2

14

您正在寻找apply. 这将调用一个函数,其参数按顺序提供。

但是您是否知道有一个功能interleave可以完全按照您的mapcatList尝试做?

于 2011-12-15T16:30:31.527 回答
5

你是对的,作为可变参数声明的结果,参数被包装在一个列表中。您需要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)
于 2011-12-15T16:26:41.493 回答