与地图一样,集合是关联的和无序的。与包含从键到值的映射的映射不同,集合实际上是从键映射到它们自身。

一个集合由大括号表示,前面是一个八角形:

#{}
;;=> #{}

#{:foo}
;;=> #{:foo}

#{:foo :bar}
;;=> #{:bar :foo}

与地图一样,元素在文字集中出现的顺序无关紧要:

(= #{:foo :bar} #{:bar :foo})
;;=> true

你可以使用 set? 谓词测试某些内容是否为集合 :

(set? #{})
;;=> true

(set? #{:foo})
;;=> true

(set? #{:foo :bar})
;;=> true

(set? nil)
;;=> false

(set? 42)
;;=> false

(set? :foo)
;;=> false

你可以使用 contains? 谓词测试地图是否在常量时间内包含给定项目 :

(contains? #{} :foo)
;;=> false

(contains? #{:foo} :foo)
;;=> true

(contains? #{:foo} :bar)
;;=> false

(contains? #{} nil)
;;=> false

(contains? #{nil} nil)
;;=> true

另外,set 本身是一个函数,它接受一个元素,如果它存在于集合中则返回该元素,如果不存在则返回 nil

(#{} :foo)
;;=> nil

(#{:foo} :foo)
;;=> :foo

(#{:foo} :bar)
;;=> nil

(#{} nil)
;;=> nil

(#{nil} nil)
;;=> nil

你可以使用 conj 获取具有现有集合的所有元素的集合,以及一个附加项目:

(conj #{} :foo)
;;=> #{:foo}

(conj (conj #{} :foo) :bar)
;;=> #{:bar :foo}

(conj #{:foo} :foo)
;;=> #{:foo}

你可以使用 disj 获取具有现有集合的所有元素的集合,减去一个项目:

(disj #{} :foo)
;;=> #{}

(disj #{:foo} :foo)
;;=> #{}

(disj #{:foo} :bar)
;;=> #{:foo}

(disj #{:foo :bar} :foo)
;;=> #{:bar}

(disj #{:foo :bar} :bar)
;;=> #{:foo}

count 以恒定时间返回元素数:

(count #{})
;;=> 0

(count (conj #{} :foo))
;;=> 1

(count #{:foo :bar})
;;=> 2

你可以使用 seq 获取集合中所有元素的序列:

(seq #{})
;;=> nil

(seq #{:foo})
;;=> (:foo)

(seq #{:foo :bar})
;;=> (:bar :foo)