Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

group-by by multiple keys in Clojure

Tags:

clojure

How to group a collection of maps by multiple keys?

For example:

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

I'd like to return this:

[{: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}]]
like image 392
Ron P Avatar asked Feb 01 '12 00:02

Ron P


1 Answers

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

This returns a map:

{{: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}]}

To get exactly the return value you specified, wrap it in (vec (apply concat ...)):

(vec (apply concat (group-by #(select-keys % [:a :b]) m1)))
; => as in the question text

This is equivalent, but perhaps prettier:

(->> (group-by #(select-keys % [:a :b]) m1)
     (apply concat)
     vec)
like image 129
Michał Marczyk Avatar answered Oct 25 '22 01:10

Michał Marczyk