返回 导航

Swift

hangge.com

Swift - 集合(Set)使用详解(附样例)

作者:hangge | 2017-12-15 08:10

一、基本介绍

1,集合的作用


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)")
}

(2)如果想按照特定顺序来遍历一个 Set 中的值可以使用 sorted() 方法。它将返回一个有序数组,这个数组的元素排列顺序由操作符“<”对元素进行比较的结果来确定。
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 的所有基本类型(如 StringIntDoubleBool)默认都是可哈希化的,可以作为集合的值的类型或者字典的键的类型。没有关联值的枚举成员值默认也是可哈希化的。

2,自定义类型的哈希化

(1)如果想要自定义的类型作为集合的值类型或者是字典的键类型,那么这个自定义类型必需符合 Swift 标准库中的 Hashable 协议。符合 Hashable 协议的类型需要提供一个类型为 Int 的可读属性 hashValue
(2)因为 Hashable 协议符合 Equatable 协议,所以遵循该协议的类型也必须提供一个"是否相等"运算符(==)的实现。这个 Equatable 协议要求任何符合 == 实现的实例间都是一种相等的关系。也就是说,对于 abc 三个值来说,== 的实现必须满足下面三种情况:
  • 自反性: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)

回到顶部