在上一篇Swift Arrays文章中,我们了解了如何创建可以在一个有序列表中包含多个值的数组。
但是,如果必须确保列表只能容纳一次值,则可以在Swift中使用一个集合。
什么是集合?
集只是一个容器,可以在无序列表中保存多个数据类型的值,并确保容器中的元素唯一(即每个数据仅出现一次)。
无序列表意味着您将不会以与Set中定义的项目相同的顺序获得元素。
在数组上使用Sets的主要优点是,当您需要确保一个项目仅出现一次并且项目的顺序不重要时。
存储在集合中的值必须是可哈希的 。这意味着它必须提供一个hashValue属性。这很重要,因为集合是无序的,并且它使用hashValue用于访问集合的元素。
Swift的所有基本类型(例如String
, Int
, Double
和Bool
)默认都是可哈希的,并且可以用作设置值类型。但是,您还可以在Swift中创建可存储在集合中的哈希类型。
如何在Swift中声明集合?
您可以通过将类型指定为Set,然后将其存储在<>中的数据类型指定为空集。
示例1:声明一个空集
let emptyIntSet:Set = []
print(emptyIntSet)
要么
let emptyIntSet:Set = Set()
print(emptyIntSet)
运行该程序时,输出为:
[ ]
在上面的程序中,我们声明了一个类型为Set
的常数emptyIntSet ,它可以存储多个整数值并用0值初始化。
由于Swift是一种类型推断语言,因此您也可以不指定数据类型而直接创建set,但是必须使用一些值进行初始化,以便编译器可以将其类型推断为:
示例2:声明具有某些值的集合
let someIntSet:Set = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(someIntSet)
运行该程序时,输出为:
[2, 4, 9, 5, 6, 7, 3, 1, 8]
在上面的程序中,我们声明了一个常量someIntSet ,可以存储Integer的集合而无需显式指定类型。但是,在定义变量时,我们需要编写:Set
,否则Swift将为我们创建一个数组。
另外,作为数组,我们使用[]
括号将集合初始化为1、2、3、4、5、6、7、8、9值。
如您print(someIntSet)
,当您尝试将集合内的值打印为print(someIntSet)
,将以与定义集合中项不同的顺序获得结果,因为它存储的值没有定义的顺序。因此,每次访问订单时都会更改。
示例3:声明具有重复值的集合
let someStrSet:Set = ["ab","bc","cd","de","ab"]
print(someStrSet)
运行该程序时,输出为:
["de", "ab", "cd", "bc"]
在上面的程序中,我们在集合中定义了重复值ab 。和。当我们尝试使用print(someStrSet)
访问集合内的值时,重复值将自动从集合中删除。因此,set保证了其中的唯一元素/值。
您还可以在Swift中使用自己的自定义Hashable类型声明一个集合。要了解更多信息,请访问Swift Hashable 。
如何在Swift中访问set元素?
您不能使用下标语法作为数组访问集合的元素。这是因为集合是无序的,并且没有索引来访问元素。
因此,您需要使用其方法和属性或使用for-in循环来访问集合。
示例4:访问集合中的元素
var someStrSet:Set = ["ab", "bc", "cd", "de"]
for val in someStrSet {
print(val)
}
运行该程序时,输出为:
de
ab
cd
bc
在上面的程序中,我们得到的val与集合中元素的顺序不同,因为集合与数组不同,它们是无序的。
您还可以访问集合的元素,如下所示直接从集合中删除值:
示例5:使用remove()访问集合中的元素
var someStrSet:Set = ["ab", "bc", "cd", "de"]
let someVal = someStrSet.remove("cd")
print(someVal)
print(someStrSet)
运行该程序时,输出为:
Optional("cd")
["de", "ab", "bc"]
在上面的程序中,您可以看到remove方法返回一个可选字符串。因此,建议您执行以下可选处理。要了解有关可选的更多信息,请访问Swift可选。
示例6:remove()的可选处理
var someStrSet:Set = ["ab", "bc", "cd", "de"]
if let someVal = someStrSet.remove("cd") {
print(someVal)
print(someStrSet)
} else {
print("cannot find element to remove")
}
运行该程序时,输出为:
cd
["de", "ab", "bc"]
如何在集合中添加新元素?
您可以使用Swift中的insert()
方法将新元素添加到集合中。
示例7:使用insert()添加新元素
var someStrSet:Set = ["ab", "bc", "cd", "de"]
someStrSet.insert("ef")
print(someStrSet)
运行该程序时,输出为:
["ab", "de", "cd", "ef", "bc"]
在上面的程序中,我们使用了集合的insert()
方法向集合添加新元素。由于集合是无序的,因此未知插入元素的位置。
集合例子
使用集合的另一个主要优点是,您可以执行集合操作,例如将两个集合组合在一起,确定两个集合具有哪些共同的值等。此操作类似于数学中的集合操作。
1.并集
两个集合a和b的并集是a或b或a和b两者中的元素的集合。
let a: Set = [1, 3, 5, 7, 9]
let b: Set = [0, 2, 4, 6, 8]
print(a.union(b))
当您运行上述程序时,输出将是:
[8, 2, 9, 4, 5, 7, 6, 3, 1, 0]
2.交集
两个集合a和b的交集是包含a的所有元素的集合,这些元素也属于b。
let a: Set = [1, 3, 5, 7, 9]
let b: Set = [0, 3, 7, 6, 8]
print(a.intersection(b))
当您运行上述程序时,输出将是:
[7, 3]
因此, print(a.intersection(b))
输出一个新集合,其值在a和b中都是通用的[ print(a.intersection(b))
] 。
3.减法
两个集合a和b的减法是包含a的所有元素但除去也属于b的元素的集合。
let a: Set = [1, 3, 5, 7, 9]
let b: Set = [0, 3, 7, 6, 8]
print(a.subtracting(b))
当您运行上述程序时,输出将是:
[5, 9, 1]
因此, print(a.subtracting(b))
输出值[ print(a.subtracting(b))
的新集合。
4.对称差异
两个集合a和b的对称差是包含所有元素的集合,这些元素位于两个集合中的任何一个中,但不在两个集合中。
let a: Set = [1, 3, 5, 7, 9]
let b: Set = [0, 3, 7, 6, 8]
print(a.symmetricDifference(b))
当您运行上述程序时,输出将是:
[5, 6, 8, 0, 1, 9]
因此, print(a.symmetricDifference(b))
输出值[ print(a.symmetricDifference(b))
的新集合。
集合成员资格和集合运算符
集合==
您可以使用==
运算符来检查两个集合是否包含相同的元素。如果两个集合包含相同的元素,则返回true,否则返回false。
示例5:集合相等操作
let a: Set = [1, 3, 5, 7, 9]
let b: Set = [0, 3, 7, 6, 8]
let c:Set = [9, 7, 3, 1, 5]
if a == b {
print("a and b are same")
} else {
print("a and b are different")
}
if a == c {
print("a and c are same")
} else {
print("a and c are different")
}
当您运行上述程序时,输出将是:
a and b are different
a and c are same
集合成员资格
您还可以使用以下方法检查两个集合之间的关系:
isSubset(of:)
此方法确定指定集合中是否包含集合的所有值。isSuperset(of:)
此方法确定一个集合是否包含指定集合中的所有值isStrictSubset(of:
isStrictSuperset(of:)
或isStrictSuperset(of:)
:此方法确定集合是子集还是超集,但不等于指定的集。isDisjoint(with:)
此方法确定两个集合是否没有共同的值。
示例6:集合成员资格操作
let a: Set = [1, 3, 5, 7, 9]
let b: Set = [0, 3, 1, 7, 6, 8, 9, 5]
print("isSubset:", a.isSubset(of: b))
print("isSuperset:", b.isSuperset(of: a))
print("isStrictSubset:", a.isStrictSubset(of: b))
print("isDisjointWith:", a.isDisjoint(with: b))
当您运行上述程序时,输出将是:
isSubset: true
isSuperset: true
isStrictSubset: true
isDisjointWith: false
让我们分析下面的print语句中使用的方法:
isSubset
返回true
因为集合b包含a中的所有元素isSuperset
返回true
因为b包含a的所有值。isStrictSubset
返回true
因为set b包含a中的所有元素并且两个set不相等。isDisjointWith
返回false
因为a和b具有一些共同的值。
内置的一些有用的Set函数和属性
1. isEmpty
此属性确定集合是否为空。它返回true
,如果一组不包含任何值,否则返回false
。
示例7:isEmpty如何工作?
let intSet:Set = [21, 34, 54, 12]
print(intSet.isEmpty)
运行该程序时,输出为:
false
2.first
此属性用于访问集合的第一个元素。
示例8:first
如何工作?
let intSet = [21, 34, 54, 12]
print(intSet.first)
运行该程序时,输出为:
Optional(54)
由于set是无序集合,因此first属性不能保证set的第一个元素。您可能会获得54以外的其他值。
同样,您可以使用last
属性访问集合的最后一个元素。
3.insert
insert 函数用于在集合中插入/追加元素。
示例9:插入如何工作?
var intSet:Set = [21, 34, 54, 12]
intSet.insert(50)
print(intSet)
运行该程序时,输出为:
[54, 12, 50, 21, 34]
4.反转reversed
此函数以相反的顺序返回集合的元素。
示例10:reversed()如何工作?
var intSet:Set = [21, 22, 23, 24, 25]
print(intSet)
let reversedSet = intSet.reversed()
print(reversedSet)
运行该程序时,输出为:
[22, 23, 21, 24, 25]
[25, 24, 21, 23, 22]
5.计数count
此属性返回集合中元素的总数。
示例11:计数如何工作?
let floatSet:Set = [10.2, 21.3, 32.0, 41.3]
print(floatSet.count)
运行该程序时,输出为:
4
6. removeFirst
此函数从集合中删除并返回第一个值。
示例12:removeFirst如何工作?
var strSet:Set = ["ab", "bc", "cd", "de"]
let removedVal = strSet.removeFirst()
print("removed value is \(removedVal)")
print(strSet)
运行该程序时,输出为:
removed value is de
["ab", "cd", "bc"]
同样,您也可以使用removeAll
函数清空集合。