Set 访问和修改
优质
小牛编辑
125浏览
2023-12-01
Swift 5.x Set 访问和修改
1.遍历 Set
- 可以使用
for-in
遍历Set
- 因为
Set
是无序的, 如果要顺序遍历Set
, 使用sorted()
方法
let courses: Set = ["Math", "English", "History"]
for course in courses {
print(course)
}
print("--- 分割线 ---")
for course in courses.sorted() {
print(course)
}
输出结果:
English
History
Math
--- 分割线 ---
English
History
Math
2. 访问Set
- 使用
count
获取Set
里元素个数 - 使用
isEmpty
判断Set
是否为空
let set: Set<Character> = ["A", "B", "C"]
print(set.count)
print(set.isEmpty)
输出结果:
3
false
3. 添加元素
insert(_:)
添加一个元素到Set
update(with:)
如果已经有相等的元素(哈希一样), 替换为新元素. 如果Set
中没有, 则插入.
struct Person {
var name: String = ""
var age: Int = 0
}
extension Person: Hashable {
func hash(into hasher: inout Hasher) {
hasher.combine(name)
}
}
extension Person: Equatable {
static func == (lhs: Person, rhs: Person) -> Bool {
return lhs.name == rhs.name
}
}
var personSet: Set<Person> = [
Person(name: "zhangsan", age: 23),
Person(name: "lisi", age: 20)
]
personSet.update(with: Person(name: "zhangsan", age: 24))
print(personSet)
这里的Person 只计算name的哈希值, 并且只根据name判断两个Person对象是否相等
输出结果:
[
__lldb_expr_148.Person(name: "zhangsan", age: 24),
__lldb_expr_148.Person(name: "lisi", age: 20)
]
由于这里只计算name
的哈希值, 所以执行udpate
时, 将原有的数据进行了更新, 而没有新增
如果改成
hasher.combine(name)
hasher.combine(age)
则会新增一条记录
[
__lldb_expr_150.Person(name: "zhangsan", age: 23),
__lldb_expr_150.Person(name: "zhangsan", age: 24),
__lldb_expr_150.Person(name: "lisi", age: 20)
]
4. 移除元素
- 4.1
filter(_:)
返回一个新的Set
, 新Set
的元素是原始Set
符合条件的元素.
struct Person {
var name: String = ""
var age: Int = 0
}
extension Person: Hashable {
func hash(into hasher: inout Hasher) {
hasher.combine(name)
hasher.combine(age)
}
}
extension Person: Equatable {
static func == (lhs: Person, rhs: Person) -> Bool {
return lhs.name == rhs.name
}
}
var personSet: Set<Person> = [
Person(name: "zhangsan", age: 23),
Person(name: "lisi", age: 20),
Person(name: "wangwu", age: 27)
]
let filterdSet = personSet.filter({$0.age < 25})
print(filterdSet)
输出结果:
[
__lldb_expr_152.Person(name: "zhangsan", age: 23),
__lldb_expr_152.Person(name: "lisi", age: 20)
]
- 4.2
remove(_:)
从Set
当中移除一个元素, 如果元素是Set
的成员就移除它, 并且返回移除的值, 如果集合没有这个成员就返回nil
struct Person {
var name: String = ""
var age: Int = 0
}
extension Person: Hashable {
func hash(into hasher: inout Hasher) {
hasher.combine(name)
hasher.combine(age)
}
}
extension Person: Equatable {
static func == (lhs: Person, rhs: Person) -> Bool {
return lhs.name == rhs.name
}
}
var personSet: Set<Person> = [
Person(name: "zhangsan", age: 23),
Person(name: "lisi", age: 20),
Person(name: "wangwu", age: 27)
]
let removedElement: Person? = personSet.remove(Person(name: "zhangsan", age: 22))
print(removedElement ?? "集合不存在该元素")
由于age
在哈希值计算范围内, 所以打印结果为
集合不存在该元素
如果去掉hasher.combine(age)
这一行代码, 打印结果:
Person(name: "zhangsan", age: 23)
- 4.3
removeAll()
移除所有元素
personSet.removeAll()
print(personSet)
输出结果:
[]
- 4.4
removeFirst()
移除Set
的第一个元素, 因为Set
是无序的, 所以第一个元素并不是放入的第一个元素, 而是哈希计算排序后的第一个元素.
struct Person {
var name: String = ""
var age: Int = 0
}
extension Person: Hashable {
func hash(into hasher: inout Hasher) {
hasher.combine(name)
}
}
extension Person: Equatable {
static func == (lhs: Person, rhs: Person) -> Bool {
return lhs.name == rhs.name
}
}
var personSet: Set<Person> = [
Person(name: "zhangsan", age: 23),
Person(name: "lisi", age: 20),
Person(name: "wangwu", age: 27)
]
personSet.removeFirst()
print(personSet)
输出结果:
[
__lldb_expr_175.Person(name: "lisi", age: 20),
__lldb_expr_175.Person(name: "wangwu", age: 27)
]
5. 基于Set
操作的
- 5.1
intersection(_:)
交集, 由属于A
且属于B
的相同元素组成的集合, 记作AnB
或BnA
- 5.2
union(_:)
并集, 由所有属于集合A
或属于集合B
的元素所组成的集合, 记作AuB
或BuA
- 5.3
symmetricDifference(_:)
对称差集, 集合A
与集合B
中所有不属于AnB
的元素的集合. - 5.4
subtracting(_:)
相对补集, 由属于A
而不属于B
的元素组成的集合, 成为B
关于A
的相对补集, 记作A-B
或A\B
e.g.
let set1: Set<Character> = ["A", "B", "C"]
let set2: Set<Character> = ["B", "E", "F", "G"]
print("交集 AnB: " + set1.intersection(set2))
print("并集 AuB: " + set1.union(set2))
print("对称差集: " + set1.symmetricDifference(set2))
print("相对补集 A-B: " + set1.subtracting(set2))
输出结果:
```bash
交集 AnB: B
并集 AuB: FGBCAE
对称差集: GCEAF
相对补集 A-B: AC
5. Set
判断方法
isSubset(of:)
判断是否是另外一个Set
或者Sequence
的子集isSuperset(of:)
判断是否是另外一个Set
或者Sequence
的超集isStrictSubset(of:)
和isStrictSuperset(of:)
判断是否是另外一个Set
的子集或者超集, 但是又不等于另外一个Set
isDisjoint(with:)
判断两个Set
是否有公共元素, 如果没有返回true
, 如果有返回false
let smallSet: Set = [1, 2, 3]
let bigSet: Set = [1, 2, 3, 4]
print(smallSet.isSubset(of: bigSet))
print(bigSet.isSuperset(of: smallSet))
print(smallSet.isStrictSubset(of: bigSet))
print(bigSet.isStrictSuperset(of: smallSet))
print(smallSet.isDisjoint(with: bigSet))
输出结果:
true
true
true
true
false