集合
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的时候提到的函数 conj
和 into
对于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
, select
和 union
. 其中有些函数的操作的对象是map而不是set。