首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何合并clojure中的映射列表

如何合并clojure中的映射列表
EN

Stack Overflow用户
提问于 2018-04-30 14:48:39
回答 2查看 708关注 0票数 2

向我提供了一份清单地图:

代码语言:javascript
复制
({:a 1 :b ["red" "blue"]} {:a 2 :b ["green"]} {:a 1 :b ["yellow"]} {:a 2 :b ["orange"]})

我需要把它们结合起来,最终看起来是这样的:

代码语言:javascript
复制
({:a 1 :b ["red" "blue" "yellow"]} {:a 2 :b ["green" "orange"]})

其中地图是基于键"a“的值组合的。到目前为止,我有这个

代码语言:javascript
复制
(->> (sort-by :a)
     (partition-by :a)
     (map (partial apply merge)))

但是合并将覆盖"b“中的向量,最后一次合并给我

代码语言:javascript
复制
({:a 1 :b ["yellow"]} {:a 2 :b ["orange"]}) 
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-04-30 14:53:17

不要使用merge,而是使用merge-with,即

代码语言:javascript
复制
(->> a (sort-by :a) 
       (partition-by :a) 
       (map (partial 
          apply 
          merge-with (fn [x y] (if (= x y) x (into x y))))))

输出

代码语言:javascript
复制
({:a 1, :b ["red" "blue" "yellow"]} {:a 2, :b ["green" "orange"]})
票数 3
EN

Stack Overflow用户

发布于 2018-04-30 21:29:41

实际上,您并不想对任何东西进行排序或分区:这只是CPU花费在什么东西上的时间,最后您有一个尴尬的数据结构(一个映射列表),而不是一个由“重要”:a值键决定的更方便的映射。

相反,我会将其写成一个约简,其中每一步都在最终映射的适当小节中使用merge-with

代码语言:javascript
复制
(defn combine-by [k ms]
  (reduce (fn [acc m]
            (update acc (get m k) 
                    (partial merge-with into) 
                    (dissoc m k)))
          {}, ms))

之后我们就有了

代码语言:javascript
复制
user=> (combine-by :a '({:a 1 :b ["red" "blue"]} 
                        {:a 2 :b ["green"]} 
                        {:a 1 :b ["yellow"]} 
                        {:a 2 :b ["orange"]}))
{1 {:b ["red" "blue" "yellow"]}, 2 {:b ["green" "orange"]}}

这对于通过特定的:a轻松查找地图很有帮助,或者如果您希望将结果作为列表返回,您可以轻松地展开它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50102975

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档