vie*_*bel 10 group-by clojure aggregate-functions
在clojure中,我想聚合这些数据:
(def data [[:morning :pear][:morning :mango][:evening :mango][:evening :pear]])
(group-by first data)
;{:morning [[:morning :pear][:morning :mango]],:evening [[:evening :mango][:evening :pear]]}
Run Code Online (Sandbox Code Playgroud)
我的问题是:evening和:morning是多余的.相反,我想创建以下集合:
([:morning (:pear :mango)] [:evening (:mango :pear)])
Run Code Online (Sandbox Code Playgroud)
我提出了:
(for [[moment moment-fruit-vec] (group-by first data)] [moment (map second moment-fruit-vec)])
Run Code Online (Sandbox Code Playgroud)
有更惯用的解决方案吗?
我遇到过类似的分组问题.通常我最终将merge-with或update-in插入到某个seq处理步骤中:
(apply merge-with list (map (partial apply hash-map) data))
Run Code Online (Sandbox Code Playgroud)
你得到一张地图,但这只是一对键值对:
user> (apply merge-with list (map (partial apply hash-map) data))
{:morning (:pear :mango), :evening (:mango :pear)}
user> (seq *1)
([:morning (:pear :mango)] [:evening (:mango :pear)])
Run Code Online (Sandbox Code Playgroud)
但是,如果每个键出现两次,此解决方案只会获得您想要的结果.这可能更好:
(reduce (fn [map [x y]] (update-in map [x] #(cons y %))) {} data)
Run Code Online (Sandbox Code Playgroud)
这两种感觉都"更具功能性",但也有点令人费解.不要太快解除您的解决方案,它易于理解且功能足够.
| 归档时间: |
|
| 查看次数: |
2594 次 |
| 最近记录: |