Swift - 集合(Set)使用详解(附样例)
作者:hangge | 2017-12-15 08:10
一、基本介绍
1,集合的作用
- 集合(Set)是用来存储相同类型、没有确定顺序、且不重复的值。
- 也就是说当元素顺序不重要时,或者希望确保每个元素只出现一次时,可以使用集合而不是数组。
2,Array、Set、Dictionariy 三者的区别
Swift 中这三种基本的集合类型都是用来存储集合数据的,它们间的区别如下:
- 数组(Arrays)是有序数据的集。
- 集合(Sets)是无序无重复数据的集。
- 字典(Dictionaries)是无序的键值对的集。
二、创建集合
1,创建空集合
(1)Swift 中 Set 类型被写为 Set<Element>,这里的 Element 表示 Set 中允许存储的类型。下面我们通过构造器语法创建一个特定类型的空集合:
var fruits = Set<String>()
(2)如果上下文提供了类型信息,我们可以通过一个空的数组字面量创建一个空的 Set:
var fruits = Set<String>() //现在fruits中包含了一个值 fruits.insert("apple") //fruit现在是一个空的集合 fruits = []
2,创建带初始值的集合
(1)下面我们创建一个带有三个 String 类型的初始值的集合。
var fruits: Set<String> = ["apple", "pear", "orange"]
(2)当然如果数组字面量中的所有元素类型相同,可以不必写 Set 的具体类型。
var fruits: Set = ["apple", "pear", "orange"]
3,将数组转为集合
由于集合里的值是不能重复的,多余的重复值将会被丢弃掉。let array = ["apple", "apple", "orange"] let set = Set(array) print(set)
三、元素访问与操作
1,获取元素个数:count
let fruits: Set = ["apple", "pear", "orange"] print(fruits.count)
2,判断集合是否为空:isEmpty
let fruits: Set = ["apple", "pear", "orange"] if fruits.isEmpty { print("集合是空的") }else{ print("集合不是空的") }
3,添加一个新元素:insert()
fruits.insert("grape")
4,删除一个元素:remove()
- 如果删除值是该 Set 的一个元素,则删除该元素并且返回被删除的元素值。
- 如果该 Set 不包含该值,则返回 nil。
fruits.remove("apple")
5,删除所有元素:removeAll()
fruits.removeAll()
6,判断集合中是否包含特定值:contains()
if fruits.contains("apple") { print("集合中存在该元素。") }else{ print("集合中不存在该元素。") }
7,遍历集合元素
(1)可以使用 for in 循环遍历一个 Set 中的所有值。
var fruits: Set = ["apple", "pear", "orange"] for fruit in fruits { print("\(fruit)") }
var fruits: Set = ["apple", "pear", "orange"] for fruit in fruits.sorted() { print("\(fruit)") }
四、集合的操作
1,过滤集合元素
使用 filter 函数可以过滤并返回一个新的 Set。let fruits: Set = ["apple", "pear", "orange"] //过滤出以“e”结尾的所有元素 let result = fruits.filter({ $0.hasSuffix("e") }) print(result)
2,两个集合的基本操作
(1)Set 提供了如下 4 个方法来实现通过现有的两个集合创建一个新的集合:
- intersection(_:):根据两个集合中都包含的值创建的一个新的集合。
- symmetricDifference(_:):根据在一个集合中但不在两个集合中的值创建一个新的集合。
- union(_:):根据两个集合的值创建一个新的集合。
- subtracting(_:):根据不在该集合中的值创建一个新的集合。
(2)下面是一个简单的使用样例
let oddDigits: Set = [1, 3, 5, 7, 9] let evenDigits: Set = [0, 2, 4, 6, 8] let singleDigitPrimeNumbers: Set = [2, 3, 5, 7] let set1 = oddDigits.union(evenDigits).sorted() // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] let set2 = oddDigits.intersection(evenDigits).sorted() // [] let set3 = oddDigits.subtracting(singleDigitPrimeNumbers).sorted() // [1, 9] let set4 = oddDigits.symmetricDifference(singleDigitPrimeNumbers).sorted() // [1, 2, 9]
3,判断两个集合之间的关系
(1)我们可以通过如下几种方法进行判断:
- ==:判断两个集合是否包含全部相同的值。
- isSubset(of:):判断一个集合中的值是否也被包含在另外一个集合中。
- isSuperset(of:):判断一个集合中包含另一个集合中所有的值。
- isStrictSubset(of:):判断一个集合是否是另外一个集合的子集合,并且两个集合并不相等。
- isStrictSuperset(of:):判断一个集合是否是另外一个集合的父集合,并且两个集合并不相等。
- isDisjoint(with:):判断两个集合是否不含有相同的值(是否没有交集)。
(2)下面是一个简单的使用样例
let set1: Set = [1, 3, 5] let set2: Set = [1, 3, 5, 7, 9] let set3: Set = [1, 2, 3] set1 == set2 // false set1.isSubset(of: set2) // true set1.isSuperset(of: set2) // false set1.isStrictSubset(of: set2) // true set1.isStrictSuperset(of: set2) // false set1.isDisjoint(with: set3) // false
五、集合类型的哈希值
1,哈希值说明
- 一个类型如果想要存储在集合中,那么该类型必须是可哈希化的。也就是说,该类型必须提供一个方法来计算它的哈希值。
- 哈希值是 Int 类型,相等对象的哈希值必须相同。比如:a==b,那么必定有 a.hashValue == b.hashValue。
- Swift 的所有基本类型(如 String,Int,Double,Bool)默认都是可哈希化的,可以作为集合的值的类型或者字典的键的类型。没有关联值的枚举成员值默认也是可哈希化的。
2,自定义类型的哈希化
(1)如果想要自定义的类型作为集合的值类型或者是字典的键类型,那么这个自定义类型必需符合 Swift 标准库中的 Hashable 协议。符合 Hashable 协议的类型需要提供一个类型为 Int 的可读属性 hashValue。
(2)因为 Hashable 协议符合 Equatable 协议,所以遵循该协议的类型也必须提供一个"是否相等"运算符(==)的实现。这个 Equatable 协议要求任何符合 == 实现的实例间都是一种相等的关系。也就是说,对于 a、b、c 三个值来说,== 的实现必须满足下面三种情况:
- 自反性:a == a
- 对称性:a == b 意味着 b == a
- 传递性:a == b && b == c 意味着 a == c
3,样例代码
(1)这里我们自定义一个结构体(User),用来做为 Set 里的值的类型。
//自定义对象 struct User { let name: String let age: Int } //自定义对象需要符合Hashable协议 extension User: Hashable { var hashValue: Int { return name.hashValue ^ age.hashValue } } //由于Hashable协议又符合Equatable协议,所以还要提供一个"是否相等"运算符(==)的实现 func ==(lhs: User, rhs: User) -> Bool { return lhs.name == rhs.name && lhs.age == rhs.age }
(2)下面是使用样例
let a = User(name: "牛大哥", age: 55) let b = User(name: "马小弟", age: 20) let c = User(name: "牛大哥", age: 55) let arr = [ a, b, c ] let set = Set(arr) print("arr里元素个数:\(arr.count)") print("set里元素个数:\(set.count)")
全部评论(0)