2016-05-21 46 views
1

输入:[{:a "ID1" :b 2} {:a "ID2" :b 4}]Clojure的:给定的地图列表,获取特定键值的总和值

我只想补充了所有的按键:b并产生如下:

结果:6

我想过要做一个filter?把所有的数字都放到向量中,然后把它加起来,但是这好像是在做两次工作。我不能在这里使用merge-with +,因为:a中有一个字符串。我是否在这里使用了一个reduce,并带有一个可以提取相应密钥的功能?

(reduce (fn [x] (+ (x :b))) 0 list-of-maps)

它甚至会更好,如果我能保留与更新后的值({:a "ID1" :b 6})地图结构,但因为我真的不需要其它按键,只是总金额的罚款。

+0

它是保证每个映射都将包含':B'映射到一定数目的? –

回答

4

我只想加起来所有的键:B和产生如下:

结果:6

我认为可行的代码是:

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

我觉得在这里使用->>可以帮助您解决问题。

这表示要对ms采取行动,该行为被定义为地图向量,threading递增结果通过其余表单。

的第一件事是用关键字:b为每一个功能,extracing对应于该键的值,产生的序列中变换地图的每个条目:

(2 12 22) 

您可以再申请reduce准确如您在用SEQ直觉得出结果:

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 

我对你打算通过的这部分是什么困惑一点点问题:

它甚至会更好,如果我能保留与更新后的值映射结构({:一个“ID1”:乙6})

你想为:b每个值在所有地图中包含所有结果中的总和还是其他内容?

+0

为什么不这样工作'(reduce(fn [x](+(x:b)))0地图列表)' – user299709

+0

@ user299709因为你传给['reduce']的函数(http:///clojuredocs.org/clojure.core/reduce)必须有两个参数。 –

+0

@SamEstep啊,因为它是'key value',那么我只是用'[k v]' – user299709

1
(reduce + (map :b list-of-maps)) 
0

这很简单,但它的工作原理! 用户=>(+(您的地图:B)(您的地图:b))的

user=> (def x [{:a "ID1" :b 2} {:a "ID2" :b 4}]) 
#'user/x 
user=> (+ ((first x) :b) ((second x) :b)) 
6 
user=> 

or user=> (+ ((nth x 0) :b) ((nth x 1) :b)) 
6