【问题标题】:Clojure merge list of maps based on keysClojure 基于键的地图合并列表
【发布时间】:2018-05-09 19:53:39
【问题描述】:

我需要转换以下数据:

[{["A" 1] [{:ms "A", :s 1, :v 15}], ["A" 2] [{:ms "A", :s 2, :v 18}], ["A" 4] [{:ms "A", :s 4, :v 19}]}
 {["A" 1] [{:ms "A", :s 1, :v2 5}], ["A" 2] [{:ms "A", :s 2, :v2 8}], ["B" 4] [{:ms "B", :s 4, :v2 9}]}]

到:

[{:ms "A", :s 1, :v 15, :v2 5} {:ms "A", :s 2, :v 18, :v2 8} {:ms "A", :s 4, :v 19} {:ms "B", :s 4, :v2 9}]

我正在努力实现,任何帮助将不胜感激:)

【问题讨论】:

  • 我得到了 99% 的答案,然后我意识到你的最后两张地图打破了这种模式。以下是我写的答案:gist.github.com/carcigenicate/d5c766a0407def6ac81cb6775212b12e 请注意最终结果并不完全正确。不知道如何克服这个(太早了:/)。希望有人能给你一个更完整的答案。
  • 这样的东西应该可以工作:(map (partial apply merge) (vals (apply merge-with concat data))) => ({:ms "A", :s 1, :v 15, :v2 5} {:ms "A", :s 2, :v 18, :v2 8} {:ms "A", :s 4, :v 19} {:ms "B", :s 4, :v2 9})

标签: merge clojure group-by reduce


【解决方案1】:

这可行:

(def data [{["A" 1] [{:ms "A", :s 1, :v 15}],
            ["A" 2] [{:ms "A", :s 2, :v 18}],
            ["A" 4] [{:ms "A", :s 4, :v 19}]}
           {["A" 1] [{:ms "A", :s 1, :v2 5}],
            ["A" 2] [{:ms "A", :s 2, :v2 8}],
            ["B" 4] [{:ms "B", :s 4, :v2 9}]}])

(map (partial apply merge) (vals (apply merge-with concat data)))

这里是一步一步的解释:

首先我们合并所有顶层映射,连接相等键的值:

(apply merge-with concat data)
;;=> {["A" 1] ({:ms "A", :s 1, :v 15} {:ms "A", :s 1, :v2 5}), 
;;    ["A" 2] ({:ms "A", :s 2, :v 18} {:ms "A", :s 2, :v2 8}), 
;;    ["A" 4] [{:ms "A", :s 4, :v 19}], 
;;    ["B" 4] [{:ms "B", :s 4, :v2 9}]}

那么对于地图中的每个值,我们应该合并到一个地图:

(apply merge '({:ms "A", :s 1, :v 15} {:ms "A", :s 1, :v2 5}))
;;=> {:ms "A", :s 1, :v 15, :v2 5}

所以我们应该使用map:

(map (partial apply merge) (vals (apply merge-with concat data)))
;;=> ({:ms "A", :s 1, :v 15, :v2 5}
;;    {:ms "A", :s 2, :v 18, :v2 8}
;;    {:ms "A", :s 4, :v 19}
;;    {:ms "B", :s 4, :v2 9})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-20
    • 2016-02-08
    • 1970-01-01
    • 2020-05-27
    • 1970-01-01
    • 2015-10-19
    • 1970-01-01
    相关资源
    最近更新 更多