I have collection of lists and I want to apply "reduce +" for each list in collection. I think I should combine "apply", "map" and "reduce +", but I can't understand how.
Example:
[[1 2 3] [4 5 3] [2 5 1]] => [6 12 8]
Asked
Active
Viewed 226 times
1 Answers
4
No need for apply
. map
and reduce
will work fine:
(map (partial reduce +) [[1 2 3] [4 5 3] [2 5 1]])
map
will call the function on each member of the list and partial
simply creates a 'curried' version of reduce that expects one parameter. it could also be written like #(reduce + %)
or (fn [lst] (reduce + lst))
Update
You could actually use apply in place of reduce here as well (just not both):
(map (partial apply +) [[1 2 3] [4 5 3] [2 5 1]])
Further Update
If you have any performance concerns, see the comments on this answer for some great tips by @AlexMiller

jsonmurphy
- 1,600
- 1
- 11
- 19
-
1`reduce` is preferred between these two and is likely to be faster, particularly if the sub vectors are large – Alex Miller Feb 03 '17 at 14:56
-
@AlexMiller I don't agree with that recommendation. At the moment `apply +` just delegates to `reduce +`, so the speed difference is negligible especially for large vectors. As http://stackoverflow.com/a/3153643/625403 says, `apply` always has the option to delegate to `reduce`, but could make use of some special optimizations not available to reduce; the converse is not true. – amalloy Feb 03 '17 at 16:49
-
I was specifically talking about comparing `apply +` to `reduce +` in this answer, not making a general case (although in most cases I think reduce is both clearer and faster than the apply equivalent). As you mention, apply is just overhead here, timings: https://gist.github.com/puredanger/88d0491cbb4dbf8fe98b3747963d0068 – Alex Miller Feb 03 '17 at 17:48
-
Also maybe worth mentioning is that using the anonymous function syntax is likely to be much faster than partial (removes var invocation and in some cases affects inlining). For the example here I see `(map (partial reduce +) ...)` = 17 ns, but `(map #(reduce + %) ...)` = 13 ns. – Alex Miller Feb 03 '17 at 17:51
-
@AlexMiller could you explain why reduce is faster here? tia – fl00r Feb 04 '17 at 20:29
-
The apply is going to construct an invocation of `+` like `(+ 1 2 3)`. The `+` function for >2 args will be executed with a `reduce`. So doing the apply is nothing but extra work over the top of calling `reduce` directly. Another subtle aspect is that `reduce` is actually defined twice in clojure.core. The first one happens during bootstrap (`reduce1`) and that's what `+` will use. The version you invoke directly is `reduce` and is more efficient for vectors. – Alex Miller Feb 05 '17 at 02:36