Skip to content

Instantly share code, notes, and snippets.

@oliyh
Last active August 29, 2015 14:22
Show Gist options
  • Save oliyh/46905d37561d28c18536 to your computer and use it in GitHub Desktop.
Save oliyh/46905d37561d28c18536 to your computer and use it in GitHub Desktop.
distinctive - choose how to determine distinct items in Clojure
(defn distinctive
"Like clojure.core/distinct, but can take a function f by which distinctiveness is calculated,
giving similar semantics to sort-by"
([coll] (distinctive identity coll))
([distinction-fn coll]
(let [step (fn step [xs seen]
(lazy-seq
((fn [[f :as xs] seen]
(when-let [s (seq xs)]
(if (contains? seen (distinction-fn f))
(recur (rest s) seen)
(cons f (step (rest s) (conj seen (distinction-fn f)))))))
xs seen)))]
(step coll #{}))))
;; behaves like distinct with no distinctiveness-fn
user> (distinctive [{:name "foos" :val "ball"}
{:name "epic" :val "fail"}
{:name "foos" :val "fail"}])
;; ({:name "foos", :val "ball"} {:name "epic", :val "fail"} {:name "foos", :val "fail"})
;; accepts a distinctiveness-fn which is used to determine if we've seen an element before
user> (distinctive :name
[{:name "foos" :val "ball"}
{:name "epic" :val "fail"}
{:name "foos" :val "fail"}])
;; ({:name "foos", :val "ball"} {:name "epic", :val "fail"})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment