给出一个向量:
(def vec [{:key 1, :value 10, :other "bla"}, {:key 2, :value 13, :other "bla"}, {:key 1, :value 7, :other "bla"}])
我想迭代每个元素并使用所有:value
的总和更新:value
到那一点,所以我会:
[{:key 1, :value 10, :other "bla"}, {:key 2, :value 23, :other "bla"}, {:key 1, :value 30, :other "bla"}])
我发现this用于打印结果,但我尝试在下面的代码中将prn
命令更改为update-in
,assoc-in
(从中提取上面的链接)但我没有很好地工作。
(reduce (fn [total {:keys [key value]}]
(let [total (+ total value)]
(prn key total)
total))
0 vec)
我是Clojure的新手,我怎样才能让它发挥作用?
答案 0 :(得分:2)
如果您想获得正在运行的总数,那么最简单的方法是使用reductions
:
(reductions (fn [acc ele] (+ acc (:value ele)))
0
[{:key 1, :value 10, :other "bla"}, {:key 2, :value 13, :other "bla"}, {:key 1, :value 7, :other "bla"}])
;; => (0 10 23 30)
正如您所看到的,传递给reductions
的函数与传递给reduce
的函数具有相同的签名。就像你要求每次到达新元素时都要完成reduce
。考虑它的另一种方式是,每次计算新的累加器时都会保留它,与reduce
不同,调用者只能看到最后一次计算的结果。
所以这是直接回答你问题的代码:
(->> [{:key 1, :value 10, :other "bla"}, {:key 2, :value 13, :other "bla"}, {:key 1, :value 7, :other "bla"}]
(reductions #(update %2 :value + (:value %1))
{:value 0})
next
vec)
;; => [{:key 1, :value 10, :other "bla"} {:key 2, :value 23, :other "bla"} {:key 1, :value 30, :other "bla"}]
答案 1 :(得分:1)
您可以累积:value
s:
(reductions + (map :value v))
=> (10 23 30)
(我重命名了向量v
以避免绊倒clojure.core/vec
。)
然后,您可以mapv
使用assoc
:
(let [value-sums (reductions + (map :value v))]
(mapv #(assoc %1 :value %2) v value-sums))
=> [{:key 1, :value 10, :other "bla"} {:key 2, :value 23, :other "bla"} {:key 1, :value 30, :other "bla"}]