Like maps, sets are associative and unordered. Unlike maps, which contain mappings from keys to values, sets essentially map from keys to themselves.
A set is denoted by curly braces preceded by an octothorpe:
#{}
;;=> #{}
#{:foo}
;;=> #{:foo}
#{:foo :bar}
;;=> #{:bar :foo}
As with maps, the order in which elements appear in a literal set doesn't matter:
(= #{:foo :bar} #{:bar :foo})
;;=> true
You can test whether something is a set using the set?
predicate:
(set? #{})
;;=> true
(set? #{:foo})
;;=> true
(set? #{:foo :bar})
;;=> true
(set? nil)
;;=> false
(set? 42)
;;=> false
(set? :foo)
;;=> false
You can test whether a map contains a given item in "constant" time using the contains?
predicate:
(contains? #{} :foo)
;;=> false
(contains? #{:foo} :foo)
;;=> true
(contains? #{:foo} :bar)
;;=> false
(contains? #{} nil)
;;=> false
(contains? #{nil} nil)
;;=> true
In addition, sets themselves are functions that take an element and return that element if it is present in the set, or nil
if it isn't:
(#{} :foo)
;;=> nil
(#{:foo} :foo)
;;=> :foo
(#{:foo} :bar)
;;=> nil
(#{} nil)
;;=> nil
(#{nil} nil)
;;=> nil
You can use conj
to get a set that has all the elements of an existing set, plus one additional item:
(conj #{} :foo)
;;=> #{:foo}
(conj (conj #{} :foo) :bar)
;;=> #{:bar :foo}
(conj #{:foo} :foo)
;;=> #{:foo}
You can use disj
to get a set that has all the elements of an existing set, minus one item:
(disj #{} :foo)
;;=> #{}
(disj #{:foo} :foo)
;;=> #{}
(disj #{:foo} :bar)
;;=> #{:foo}
(disj #{:foo :bar} :foo)
;;=> #{:bar}
(disj #{:foo :bar} :bar)
;;=> #{:foo}
count
returns the number of elements, in constant time:
(count #{})
;;=> 0
(count (conj #{} :foo))
;;=> 1
(count #{:foo :bar})
;;=> 2
You can get a sequence of all elements in a set using seq
:
(seq #{})
;;=> nil
(seq #{:foo})
;;=> (:foo)
(seq #{:foo :bar})
;;=> (:bar :foo)