2013-09-22 58 views
7

我想了解在clojure中对不同尺寸集合进行操作的惯用方式。有没有一种方法可以告诉函数'map'用一些默认值填充集合的其余部分?在clojure中使用具有不同尺寸集合的'地图'

作为一个例子,假设我有3个载体:

(def x [1 2 3 4]) 
(def y [1 2 3 4 5]) 
(def z [1 2 3 4 5 6 7]) 

(map + x y z) ; yields (3 6 9 12) 

在这种情况下,我怎样才能垫x和y用零和具有此收率:

(3 6 9 12 10 6 7) 

回答

10

map不自己动手,但您可以结合使用concatrepeat以获得理想的结果:

(def x [1 2 3 4]) 
(def y [1 2 3 4 5]) 
(def z [1 2 3 4 5 6 7]) 

(map + 
    (concat x (repeat 0)) 
    (concat y (repeat 0)) 
    z) ; => (3 6 9 12 10 6 7) 

以下是concatrepeat的API文档。

这里是一个草图,说明如何将这些内容抽象出来,所以你不需要知道哪些集合是最长的。 (在上面的代码片段中,如果你的concat的所有集合都是(repeat 0),那么你将拥有无限的序列)。

(defn map-longest 
    [f default & colls] 
    (lazy-seq 
    (when (some seq colls) 
    (cons 
     (apply f (map #(if (seq %) (first %) default) colls)) 
     (apply map-longest f default (map rest colls)))))) 

(map-longest + 
      0 
      [1 2 3 4] 
      [1 2 3 4 5] 
      [1 2 3 4 5 6 7]) ; => (3 6 9 12 10 6 7) 

您可以看到一些其他方法作为this previous question on Stack Overflow的答案。