Input: [{:a "ID1" :b 2} {:a "ID2" :b 4}]
I want to only add up all the keys :b
and produce the following:
Result: 6
I thought about doing a filter?
to pull all the numbers into vector and add it all up but this seems like doing work twice. I can't use merge-with +
here since the :a
has a string in it. Do I use a reduce
here with a function that will pull the appropriate key?
(reduce (fn [x] (+ (x :b))) 0 list-of-maps)
It would be even nicer if I could retain the map structure with updated value ({:a "ID1" :b 6})
but since I don't really need the other keys, just the total sum is fine.
I want to only add up all the keys :b and produce the following:
Result: 6
I believe workable code is:
(def m1 {:a 1, :b 2})
(def m2 {:a 11, :b 12})
(def m3 {:a 21, :b 22})
(def ms [m1 m2 m3])
(->> ms
(map :b)
(reduce +))
I feel use of ->>
here can help readability in your situation.
This says to take action on ms
, which is defined to be a vector of maps, threading incremental results through the remaining forms.
The first thing is to transform each entry of maps using the keyword :b
as a function on each, extracing the value corresponding to that key, resulting in the sequence:
(2 12 22)
You can then apply reduce
exactly as you intuit across that seq to get the result:
user=> (def m1 {:a 1, :b 2})
#'user/m1
user=> (def m2 {:a 11, :b 12})
#'user/m2
user=> (def m3 {:a 21, :b 22})
#'user/m3
user=> (def ms [m1 m2 m3])
#'user/ms
user=> (->> ms
#_=> (map :b)
#_=> (reduce +))
36
I'm a tad confused by what you intend by this part of the question:
It would be even nicer if I could retain the map structure with updated value ({:a "ID1" :b 6})
Do you want to have each value for :b
across all maps contain the sum of them all in a result, or something else?