Sets
Prerequisites: Maps
A set #{...} holds unique values with fast membership tests.
(def tags #{:clojure :jvm :lisp})
(println (contains? tags :jvm))
(println (tags :lisp) (tags :python)) ; a set is a function too
(println (conj tags :fp))
(println (disj tags :jvm))
(println (count (conj tags :jvm))) ; already there: no change
(println (set [1 2 2 3 3 3]))
(println (sorted-set 3 1 2))
true
:lisp nil
#{:lisp :clojure :jvm :fp}
#{:lisp :clojure}
3
#{1 3 2}
#{1 2 3}
Calling a set with a value returns the value if it's present and nil
otherwise, so a set works as a predicate:
(def vowel? #{\a \e \i \o \u})
(println (filter vowel? "programming"))
(println (remove #{0} [1 0 2 0 3]))
(o a i)
(1 2 3)
Set operations
(require '[clojure.set :as set])
(def backend #{"ada" "linus" "grace"})
(def frontend #{"grace" "tim"})
(println (sort (set/union backend frontend)))
(println (set/intersection backend frontend))
(println (sort (set/difference backend frontend)))
(println (set/subset? #{"tim"} frontend))
(ada grace linus tim)
#{grace}
(ada linus)
true
Set order isn't defined, so the examples sort results before printing.
clojure.set also has relational functions like join, index, and
rename-keys for sets of maps.