讨论swift中的Set以及它与Array的区别
Set
首先给出
Set
在源码中的定义struct Set<Element> where Element : Hashable
Set
是swift中的集合类型,用来储存相同类型且没有确定顺序的值,所以Set
使用时必须明确指定它的类型,当然如果使用字面量初始化方法的话编译器会帮我们推断Set
中包含的元素类型。需要注意的是,Set
中的元素只可以出现一次,也就是说每个元素的值是不能重复的,这点区别于数组。所以,当我们希望我们的数据结构不在意元素存放的顺序,但是对于唯一性有严格要求时,我们可以使用Set
而非Array
此外,swift中的Set
被桥接至Foundation
框架也就是Objective-C中的NSSet
类型。
三大特性
- 确定性:给定某一个
Set
,对于某一元素,它属于或不属于该集合,其二者必居其一。 - 无序性:在
Set
中,我们的元素的存放顺序是无序的,也就是说每个元素没有先后顺序。由定义中可知,集合的元素必须实现Hashable
协议,这为无序性提供了基础,也就是说Set
可以是由哈希表构成,从而实现无序。 - 确定性:在
Set
中,每个元素都互不相同,相同的值只能出现一次。
创建方法
- 初始化器构建。此时必须指定集合的类型。
- 字面量构建。可以使用数组的字面量构建方法来构建一个集合,当然里面的元素必须是同类型的,此时编译器会自动推断这个集合的类型。
遍历
- 和数组类似,我们可以使用
For - in
来遍历集合,如果我们需要按序遍历集合,可以先使用sorted()
来获得有序的集合。
Set
常用API
- 首先集合必用到的一个操作就是插入:
mutating func insert(_ newMember: Element) -> (inserted: Bool, memberAfterInsert: Element)
. 可以看到该函数返回一个元组Tuple
。元组是一个在括号中用逗号分隔元素的类型,声明后不可以增加或者删除元素,但可以更改元素的值。取值时使用下标或声明时写的名称。常见的如多个参数或函数多个返回值即是元组。
在这里,如果要插入的值在集合中已经存在,则插入无效并会返回(false, oldMember)
,如果值不存在则成功插入并返回(true, newMember)
. - update: 与
insert
类似,但在遇到集合已存在新值时会替换掉旧值。 - filter: 这个高级函数我们并不陌生,在之前的文章里已经有细讲,这里就不在赘述。它会根据给出的条件返回一个新的
Set
- remove:
mutating func remove(_ member: Element) -> Element?
,如果值存在于集合,则移除该元素并返回该值,否则返回nil
- removeAll() / removeFirst() : 前者为移除所有元素,后者为移除第一个元素。需要注意的是,由于集合中的元素是无序的,所以调用
removeFirst()
时移除的并不一定是第一个插入的元素。
一些集合特有的集合运算
- intersection交集:
func intersection(_ other: Set<Element>) -> Set<Element>
,根据两个集合中的值返回一个交集的Set - symmetricDifference对称差集:
func symmetricDifference(_ other: Self) -> Self
,返回值在一个或另一个集合中,但不都在的集合。Returns a new option set with the elements contained in this set or in the given set, but not in both. - union并集:返回两个集合的并集
- subtract相对补集:
mutating func subtract(_ other: Set<Element>)
,去掉原有的集合中在另一个集合中也存在的元素。Removes the elements of the given set from this set.
一些判断方法
- isSubset(of:)子集:
func isSubset(of other: Set<Element>) -> Bool
,Returns a Boolean value that indicates whether this set is a subset of the given set. - isSuperset(of:)超集:A是B的子集,则B是A的超集,返回一个Bool值。
- isStrictSubset(of:)真子集:A是B的子集但A不等于B,则A是B的真子集。返回一个Bool值
- isDisjoint(with:)是否有公共元素:返回一个Bool值,判断是否两个集合有公共元素,即是否没有交集。
最后
以上是Set
的大概介绍,当我们对数据的唯一性有严格要求时可以使用Set,同时我们也可以使用它的集合运算来处理我们的数据以实现特定需求。
Tino Wu