简体   繁体   中英

Clojure reducer/map not working

I've an algorithm as follows -

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

which works fine.

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

It basically finds the maximum element on each position. 7 is the largest first element is the collection and 9 is the largest second element. However, when trying to use reducer/map from core.reducers , i get

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

So this does not work -

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

Why?

UPDATE

my final code is

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

Running a quick bench on it gives Execution time mean : 626.125215 ms

I've got this other algorithm that I wrote before -

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

which does that same thing. For this i got - Execution time mean : 308.200310 ms which is twice as fast than the r/fold parallel thingy. Any ideas why?

Btw, if I remove into [] from the r/fold stuff, then I get Execution time mean : 13.101313 ms .

r/map takes [f] or [f coll] - so your apply approach won't work here

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

The answer to the question why has already been given. So let's answer the next question: "what are you trying to do?"

According to how i've understood your goal (find maximum elements by the position in tuples) and to do it potentially in parallel (as you are trying to use reducers), that's what you have to do

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

or even better with destructuring:

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

update: for large data you should optimize it and switch to using vectors

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM