Clojure reducer / map not working

时间:2015-10-19 15:51:04

标签: dictionary clojure mapreduce

我的算法如下 -

(defn max-of
[args]
(into [] (apply map #(apply max %&) args)))

工作正常。

(max-of [[1 7] [3 5] [7 9] [2 2]])返回[7 9]

它基本上找到每个位置的最大元素。 7是最大的第一个元素是集合,9是最大的第二个元素。但是,在尝试使用reducer/map中的core.reducers时,我会

CompilerException clojure.lang.ArityException: Wrong number of args (21) passed to: reducers/map

所以这不起作用 -

(defn max-of
[args]
(into [] (apply r/map #(apply max %&) args)))

为什么?

更新

我的最终代码是

(defn max-of [[tuple & tuples]]
  (into [] (r/fold (fn
            ([] tuple)
            ([t1 t2] (map max t1 t2)))
          (vec tuples))))

在其上运行快速工作台会提供Execution time mean : 626.125215 ms

我之前写过其他算法 -

(defn max-fold
    [seq-arg]
    (loop [acc (transient []) t seq-arg]
        (if (empty? (first t))
            (rseq (persistent! acc))
            (recur (conj! acc (apply max (map peek t))) (map pop t)))))

做同样的事情。为此,我得到了 - Execution time mean : 308.200310 ms,其速度是r / fold parallely的两倍。有什么想法吗?

顺便说一句,如果我从into []内容中移除r/fold,那么我会得到Execution time mean : 13.101313 ms

2 个答案:

答案 0 :(得分:3)

r/map需要[f][f coll] - 因此您的apply方法无法在此工作

user=> (doc r/map)
-------------------------
clojure.core.reducers/map
([f] [f coll])

VS

user=> (doc map)
-------------------------
clojure.core/map
([f] [f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls])

答案 1 :(得分:2)

已经给出了为什么这个问题的答案。那么让我们回答下一个问题:“你想做什么?”

根据我如何理解你的目标(通过元组中的位置找到最大元素)并且可能并行执行(当你尝试使用reducer时),这就是你必须要做的事情

(defn max-of [tuples]
  (r/fold (fn
            ([] (first tuples))
            ([t1 t2] (map max t1 t2)))
          ((rest tuples)))

user> (max-of [[1 7] [3 5] [7 9] [2 2]])
(7 9)

(max-of [[1 2 3] [3 2 1] [4 0 4]])
(4 2 4)

user> (max-of [])
nil

user> (max-of [[1 2 3]])
[1 2 3]

甚至更好的解构:

(defn max-of [[tuple & tuples]]
  (r/fold (fn
            ([] tuple)
            ([t1 t2] (map max t1 t2)))
          tuples))

<强>更新 对于大数据,您应该优化它并切换到使用向量

(defn max-of [[tuple & tuples]]
  (r/fold (fn
            ([] tuple)
            ([t1 t2] (map max t1 t2)))
          (vec tuples)))

user> (max-of (repeat 1000000 [1 2 3 4 5 6 7 8 9 10]))
(1 2 3 4 5 6 7 8 9 10)