2012-02-01 28 views
14

如何用多个键组合多个地图?在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 :c 3}]] 

回答

18
(group-by #(select-keys % [:a :b]) m1) 

这会返回地图:

{{: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 (apply concat ...))

(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) 
+9

您还可以'(组由(juxt:A:B)科尔)',它给你对,而不是地图作为按键。通常这会比使用':a'和':b'键的几十个地图更有用,但这完全取决于您的应用程序。 – amalloy 2012-02-01 02:19:35

+0

@amalloy:对。这是我在实现规范要求制作地图之前写的。同意向量可能更有用,我应该把它包括在答案中...感谢您修复这个明显的遗漏。 :-) – 2012-02-01 02:25:11