集合

Sets 是一个包含不重复元素的集合。当我们要求集合里面的元素不可以重复,并且我们不要求集合里面的元素保持它们添加时候的顺序,那么sets是比较适合的。 Clojure 支持两种不同的set: 排序的和不排序的。如果添加到set里面的元素相互之间不能比较大小,那么一个 ClassCastException 异常会被抛出来。下面是一些创建set的方法:

(def stooges (hash-set "Moe" "Larry" "Curly")) ; not sorted
(def stooges #{"Moe" "Larry" "Curly"}) ; same as previous
(def stooges (sorted-set "Moe" "Larry" "Curly"))

contains? 函数可以操作sets和maps. 当操作set的时候, 它返回给定的set是否包含某个元素。这比在list和vector上面使用的 some函数就简单多了 . 看例子:

(contains? stooges "Moe") ; -> true
(contains? stooges "Mark") ; -> false

Sets 可以被当作它里面的元素的函数来使用. 当以这种方式来用的时候,返回值要么是这个元素,要么是nil. 这个比起contains?函数来说更简洁. 比如:

(stooges "Moe") ; -> "Moe"
(stooges "Mark") ; -> nil
(println (if (stooges person) "stooge" "regular person"))

在介绍list的时候提到的函数 conjinto 对于set也同样适用. 只是元素的顺序只有对sorted-set才有定义.

disj 函数通过去掉给定的set里面的一些元素来创建一个新的set. 看例子:

(def more-stooges (conj stooges "Shemp")) ; -> #{"Moe" "Larry" "Curly" "Shemp"}
(def less-stooges (disj more-stooges "Curly")) ; -> #{"Moe" "Larry" "Shemp"}

你也可以看看 clojure.set 名字空间里面的一些函数: difference , index , intersection , join , map-invert , project , rename , rename-keys , selectunion . 其中有些函数的操作的对象是map而不是set。