Swift-存储类型-集合

集合在集合中存储相同类型的不同值,没有定义的顺序。 当元素的顺序不重要时,或者当您需要确保元素只出现一次时,您可以使用集合而不是数组。

集类型的哈希值

类型必须是可哈希的,以便存储在集合中,即,类型必须提供一种计算自身的哈希值的方法。 哈希值是一个Int值,对于所有均等比较的对象是相同的,因此如果a == b,则遵循a.hashValue == b.hashValue。

Swift的所有基本类型(例如String,Int,Double和Bool)在默认情况下是哈希的,并且可以用作设置值类型或字典键类型。 默认情况下,没有关联值的枚举值值(如枚举中所述)也是可哈希的。

您可以使用自己的自定义类型作为设置值类型或字典键类型,使它们符合Swift标准库中的Hashable协议。 符合Hashable协议的类型必须提供一个称为hashValue的gettable Int属性。 由类型的hashValue属性返回的值不需要在同一程序的不同执行或不同程序中相同。

因为Hashable协议符合Equatable,符合类型还必须提供equals运算符(==)的实现。 可等式协议要求任何符合的==的实现是等价关系。 也就是说,对于所有值a,b和c,==的实现必须满足以下三个条件:

a == a (Reflexivity)

a == b implies b == a (Symmetry)

a == b && b == c implies a == c (Transitivity)

集合类型的语法

Swift集合的类型写为Set <Element>,其中Element是允许集合存储的类型。 与数组不同,集合没有等效的字面量。

创建并初始化一个空集合

您可以使用初始化语法创建一个特定类型的空集:

var letters = Set<Character>()
print("letters is of type Set<Character> with \(letters.count) items.")
// Prints "letters is of type Set<Character> with 0 items."

或者,如果上下文已经提供类型信息(例如函数参数或已经输入的变量或常量),则可以使用空数组文本创建空集:

letters.insert("a")
// letters now contains 1 value of type Character
letters = []
// letters is now an empty set, but is still of type Set<Character>

使用数组创建集合

您还可以使用数组文本初始化集合,作为将一个或多个值写入集合集合的简写方法。

下面的示例创建一个名为favoriteGenres的集合来存储字符串值:

var favoriteGenres: Set<String> = ["Rock", "Classical", "Hip hop"]
// favoriteGenres has been initialized with three initial items

favoriteGenres变量被声明为“一组字符串值”,写为Set <String>。 因为此特定集合已指定值类型的字符串,它只允许存储字符串值。 这里,favoriteGenres集合使用在数组文本中写入的三个String值(“Rock”,“Classical”和“Hip Hop”)初始化。

集合类型不能从数组文字单独推断,因此必须显式声明类型Set。 但是,由于Swift的类型推断,如果使用包含相同类型值的数组文本来初始化它,则不必编写集合的类型。 favoriteGenres的初始化可以写成更短的形式:

var favoriteGenres: Set = ["Rock", "Classical", "Hip hop"]

访问和修改集合

您可以通过其方法和属性访问和修改集合。

要了解集合中的元素个数,请是有那个其只读计数属性:

print("I have \(favoriteGenres.count) favorite music genres.")
// Prints "I have 3 favorite music genres."

使用布尔isEmpty属性作为检查count属性是否等于0的快捷方式:

if favoriteGenres.isEmpty {
    print("As far as music goes, I'm not picky.")
} else {
    print("I have particular music preferences.")
}
// Prints "I have particular music preferences."

您可以通过调用set的insert(_ :)方法将新项目添加到集合中:

favoriteGenres.insert("Jazz")
// favoriteGenres now contains 4 items

您可以通过调用集合的remove(_ :)方法从集合中删除元素,如果该元素是集合的成员,则会删除该元素,并返回删除的值,如果集合不包含该值,则返回nil。 或者,集合中的所有元素都可以使用removeAll()方法删除。

if let removedGenre = favoriteGenres.remove("Rock") {
    print("\(removedGenre)? I'm over it.")
} else {
    print("I never much cared for that.")
}
// Prints "Rock? I'm over it."

要检查集合是否包含特定项目,请使用contains(_ :)方法。

if favoriteGenres.contains("Funk") {
    print("I get up on the good foot.")
} else {
    print("It's too funky in here.")
}
// Prints "It's too funky in here."

遍历集合

for genre in favoriteGenres {
    print("\(genre)")
}
// Jazz
// Hip hop
// Classical

Swift的Set类型没有定义的顺序。 要以特定顺序迭代集合的值,请使用sorted()方法,该方法将使用数组的<operator运算符排序的集合的元素并返回。

for genre in favoriteGenres.sorted() {
    print("\(genre)")
}
// Classical
// Hip hop
// Jazz

执行集合的操作

您可以有效地执行基本集合操作,例如将两个集合组合在一起,确定两个集合具有共同的值,或者确定两个集合是否包含所有,一些或没有相同的值。

集合的基本操作

下面的图示描绘了两个集合a和b,其具有由阴影区域表示的各种集合操作的结果。


屏幕快照 2016-11-19 上午11.05.07.png
  • 使用intersection(_ :)方法创建一个只包含两个公共值的新集合。(交集)
  • 使用symmetricDifference(_ :)方法创建一个新集合,其值集在两个集合中,但不能同时存在。()
  • 使用union(_ :)方法创建一个包含两个集合中的所有值的新集合。(合集)
  • 使用subtracting(_ :)方法创建一个值不在指定集中的新集。(补集)
let oddDigits: Set = [1, 3, 5, 7, 9]
let evenDigits: Set = [0, 2, 4, 6, 8]
let singleDigitPrimeNumbers: Set = [2, 3, 5, 7]

oddDigits.union(evenDigits).sorted()
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
oddDigits.intersection(evenDigits).sorted()
// []
oddDigits.subtracting(singleDigitPrimeNumbers).sorted()
// [1, 9]
oddDigits.symmetricDifference(singleDigitPrimeNumbers).sorted()
// [1, 2, 9]

集合之间的关系

下面的图示描绘了三个集合a,b和c,其中重叠区域表示在集合中共享的元素。 设置a是集合b的超集,因为a包含b中的所有元素。 相反,集合b是集合a的子集,因为b中的所有元素也包含在a中。 集合b和集合c彼此不相交,因为它们不共享公共的元素。


屏幕快照 2016-11-19 上午11.12.17.png
  • 使用“is equal”运算符(==)来确定两个集合是否包含所有相同的值。
  • 使用isSubset(of :)方法来确定集合的所有值是否都包含在指定的集合中。
  • 使用isSuperset(of :)方法来确定集合是否包含指定集合中的所有值。
  • 使用isStrictSubset(of :)或isStrictSuperset(of :)方法来确定集合是否为子集或超集,但不等于指定的集合。
  • 使用isDisjoint(with :)方法来确定两个集合是否具有任何共同的值。
houseAnimals.isSubset(of: farmAnimals)
// true
farmAnimals.isSuperset(of: houseAnimals)
// true
farmAnimals.isDisjoint(with: cityAnimals)
// true
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 前言 3月27号苹果发布了Swift3.1,官方教程也更新到了3.1,查看更新记录发现更新的内容对之前的文章并没有...
    BoomLee阅读 8,334评论 0 4
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,461评论 19 139
  • 由苹果官网翻译得来fork自https://github.com/letsswift/The-Swift-Prog...
    佛祖拿屠刀阅读 3,196评论 0 1
  • Swift 语言提供Arrays、Sets和Dictionaries三种基本的集合类型用来存储集合数据。数组(Ar...
    穷人家的孩纸阅读 3,647评论 3 2
  • 527,一个很好的日子,姐姐正式领结婚证了,看着两个结婚证突然发现时间好快,从小我们一起长大,虽然期间有过误会,但...
    诗经丫丫阅读 1,755评论 0 0