Sort a Clojure map by two or more keys
Note to self. Given this:
user> (def x [{:foo 2 :bar 11}
{:bar 99 :foo 1}
{:bar 55 :foo 2}
{:foo 1 :bar 77}])
#'user/x
How do you sort by :foo, and where :foo is equal, sort by :bar?
Obviously not like this:
user> (sort x)
; Evaluation aborted.
;; java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.lang.Comparable
Also not like this:
user> (sort-by #(map % [:foo :bar]) x)
; Evaluation aborted.
;; java.lang.RuntimeException: java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to java.lang.Comparable
What's a guy got to do to find something Comparable? Well, vectors are Comparable, so we can do this:
user> (sort-by #(vec (map % [:foo :bar])) x)
({:foo 1, :bar 77} {:bar 99, :foo 1} {:foo 2, :bar 11} {:bar 55, :foo 2})

3 Comments
Nice
Your example helped me in understanding sort-by. Thanks!
Very nice.
I just spotted that it's slightly more succinct to do this :-
Speak your Mind
Preview