8

我想了解在 clojure 中对不同大小的集合进行操作的惯用方式。有没有办法告诉函数'map'用一些默认值填充集合的其余部分?

例如,假设我有 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)
4

2 回答 2

12

map它本身不会这样做,但您可以使用concat和的组合repeat来获得所需的结果:

(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)

您可以在 Stack Overflow 上看到其他几种方法作为对上一个问题的答案。

于 2013-09-22T05:39:27.147 回答
0

您可以通过以下函数合并具有可变长度的地图矢量:

(defn merge-maps
  [& args]
  (let [max-count (apply max (map #(count %1) args))
        items (map #(take max-count (concat %1 (repeat nil))) args)]
    (apply map merge items)))

此功能使解决方案更加通用,并且可以采用任意长度的地图矢量。

于 2019-08-21T05:26:20.573 回答