2

In Clojure, I have a map like this:

(def data {:a 1 :b 2 :c 3})

I want to sum all the elements and get 6 as a result. I know I should probably use reduce, but I'm at a loss at how to do it correctly.

Zaroth
  • 568
  • 7
  • 19

2 Answers2

13

There are two easy ways you can do this.

With reduce

(reduce + (vals data))

Or with apply

(apply + (vals data))

They are equivalent for associative functions.

I'd suggest that apply is more idiomatic, because + is already implemented via reduce.

That is, if we calculate (+ 1 2 3), the result is 6. So it's natural to ask why (+ (vals data)) isn't sufficient.

The result of (vals data) is the list (1 2 3). + sees this as a single argument and just returns that value... oops.

(+ (vals data))
=> (1 2 3)

apply works by essentially unpacking the list.

Community
  • 1
  • 1
munk
  • 12,340
  • 8
  • 51
  • 71
5

You are correct, you should reduce here. vals will get you the values you want to add up, then just reduce them over the addition function.

user=> (def data {:a 1 :b 2 :c 3})
#'user/data
user=> (vals data)
(3 2 1)
user=> (reduce + (vals data)) 
6
jmargolisvt
  • 5,722
  • 4
  • 29
  • 46