在Clojure中按多个键分组

在Clojure中按多个键分组,clojure,Clojure,如何按多个键对地图集合进行分组 例如: (def m1 [{:a 1 :b 2 :c 3} {:a 1 :b 2 :c 4} {:a 1 :b 4 :c 3} {:a 1 :b 4 :c 3}]) (group-by-x [:a :b] m1) 我想退这个: [{:a 1 :b 2} [{:a 1 :b 2 :c 3}{:a 1 :b 2 :c 4}], {:a 1 :b 4} [{:a 1 :b 4 :c 3}{:a 1 :b 4 :

如何按多个键对地图集合进行分组

例如:

(def m1 [{:a 1 :b 2 :c 3}
         {:a 1 :b 2 :c 4}
         {:a 1 :b 4 :c 3}
         {:a 1 :b 4 :c 3}])

(group-by-x [:a :b] m1)
我想退这个:

[{:a 1 :b 2} [{:a 1 :b 2 :c 3}{:a 1 :b 2 :c 4}],
 {:a 1 :b 4} [{:a 1 :b 4 :c 3}{:a 1 :b 4 :c 3}]]
这将返回一个映射:

{{:b 2, :a 1} [{:a 1, :c 3, :b 2} {:a 1, :c 4, :b 2}],
 {:b 4, :a 1} [{:a 1, :c 3, :b 4} {:a 1, :c 3, :b 4}]}
要准确获取指定的返回值,请将其包装在
(vec(应用concat…)

这是等效的,但可能更漂亮:

(->> (group-by #(select-keys % [:a :b]) m1)
     (apply concat)
     vec)

您还可以
(按(juxt:a:b)coll分组)
,这将为您提供成对而不是贴图作为键。通常,这是一种比拥有几十个带有
:a
:b
键的地图更有用的格式,但这完全取决于您的应用程序。@amalloy:对。这就是我在意识到规范要求映射之前写的。同意向量可能更有用,我应该把它包括在答案中。。。感谢您修复此明显的遗漏。:-)@据我所知,MichałMarczyk“选择键”返回一个映射,而映射不保证排序。我想这可能会引起一些问题,你不觉得吗?
(vec (apply concat (group-by #(select-keys % [:a :b]) m1)))
; => as in the question text
(->> (group-by #(select-keys % [:a :b]) m1)
     (apply concat)
     vec)