2012-02-01 71 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