Skip to content

Instantly share code, notes, and snippets.

@bsless
Last active October 26, 2020 10:47
Show Gist options
  • Save bsless/33fb66bf9ef30a3e56a891d59d2c0892 to your computer and use it in GitHub Desktop.
Save bsless/33fb66bf9ef30a3e56a891d59d2c0892 to your computer and use it in GitHub Desktop.
Clojure recursive group-by
;;; Based on https://stackoverflow.com/a/38842018/12373587
(defn map-vals
[m f]
(persistent!
(reduce-kv
(fn [m k v]
(assoc! m k (f v)))
(transient {})
m)))
(defn nested-group-by
"Like group-by but instead of a single function, this is given a list or vec
of functions to apply recursively via group-by. An optional `final` argument
(defaults to identity) may be given to run on the vector result of the final
group-by."
([fs coll]
(nested-group-by fs coll identity))
([[f & fs] coll final-fn]
(if f
(map-vals
(group-by f coll)
#(nested-group-by fs % final-fn))
(final-fn coll))))
(def foo [ ["A" 2011 "Dan"]
["A" 2011 "Jon"]
["A" 2010 "Tim"]
["B" 2009 "Tom"] ])
(nested-group-by [first second] foo #(map (fn [x] (nth x 2)) %))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment