前言
Swift语言提供Array、Set和Dictionary三种基本的集合类型用来存储集合数据。数组是有序的数据集;集合是无序无重复的数据集;而字典是无序的键值对数组集。
Swift的Array、Set和Dictionary类型被实现为泛型集合。因此,它所存储的元素的类型必须是一致的,同样,我们取出来的数据类型也是明确的。
集合的可变性(Mutability Of Collections)
如果创建一个Arrays、Sets或Dictionaries并且把它分配成一个变量,这个集合将会是可变的。这意味着我们可以在创建之后添加更多或移除已存在的数据项,或者改变集合中的数据项。
如果我们把Arrays、Sets或Dictionaries分配成常量,那么它就是不可变的,它的大小和内容都不能被改变。
若我们确定集合不需要改变,那么我们应该使用不可变集合,也就是使用@H_502_15@let声明,那样编译器会为我们优化。
数组(Arrays)
数组使用有序列表存储同一类型的多个值,相同的值可以多次出现在一个数组的不同位置中。我们需要明确,数组是有序的,元素类型是相同的。
Swift中的Array与Foundation中的NSArray是桥接的,可以相互转换。
创建一个空数组(Create An Empty Array)
由于Swift中的数组是泛型,因此必须指定元素的数据类型:
创建带默认值的数组(Creating An Array With A Default Value)
Swift提供了如下方法,可以创建带有默认值的数组,这个构造方法是使用count个指定元素来初始化:
Box-sizing: border-Box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: "Source Code Pro",0); Box-sizing: border-Box;"><span class="hljs-xmlDocTag" style="Box-sizing: border-Box;">///</span> Construct a Array of `count` elements,each initialized to</span> <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;"><span class="hljs-xmlDocTag" style="Box-sizing: border-Box;">///</span> `repeatedValue`.</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">public</span> <span class="hljs-title" style="Box-sizing: border-Box;">init</span>(count: Int,repeatedValue: Element)</code><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li></ul>
例如:
数组相加来创建数组(Creating An Array By Adding Two Array Togeter)
两个数组能够通过加号+
来创建一个合并的数组,是因为苹果为我们提供了这样的方法:
这是个泛型函数,要求类型RRC1和RRC2是遵守RangeReplaceableCollectionType
协议的,并且这两个集合的元素类型要求相同。而数组是遵守RangeReplaceableCollectionType
协议的,因此可以通过此方法将两个数组相加。
例如:
Box-sizing: border-Box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: "Source Code Pro",0); Box-sizing: border-Box;">// anotherThreeDoubles 被推断为 [Double],等价于 [2.5,2.5,2.5]</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">var</span> anotherThreeDoubles = <span class="hljs-built_in" style="color: rgb(102,102); Box-sizing: border-Box;">Array</span>(count: <span class="hljs-number" style="color: rgb(0,102); Box-sizing: border-Box;">3</span>,repeatedValue: <span class="hljs-number" style="color: rgb(0,102); Box-sizing: border-Box;">2.5</span>) <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;">// sixDoubles 被推断为 [Double],等价于 [0.0,136); Box-sizing: border-Box;">var</span> sixDoubles = threeDoubles + anotherThreeDoubles</code><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li><li style="Box-sizing: border-Box; padding: 0px 5px;">4</li><li style="Box-sizing: border-Box; padding: 0px 5px;">5</li></ul><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li><li style="Box-sizing: border-Box; padding: 0px 5px;">4</li><li style="Box-sizing: border-Box; padding: 0px 5px;">5</li></ul>
用数组字面量构造数组(Creating An Array With An Array Literal)
我们可以使用字面量数组来进行数组构造,这是一种用一个或者多个数值构造数组的简单方法。字面量是一系列由逗号分割并由方括号包含的数值:
Box-sizing: border-Box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: "Source Code Pro",0); Box-sizing: border-Box;">// shoppingList 已经被构造并且拥有两个初始项。</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">var</span> shoppingList: [<span class="hljs-built_in" style="color: rgb(102,102); Box-sizing: border-Box;">String</span>] = [<span class="hljs-string" style="color: rgb(0,136,0); Box-sizing: border-Box;">"Eggs"</span>,<span class="hljs-string" style="color: rgb(0,0); Box-sizing: border-Box;">"Milk"</span>]</code><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li></ul>
由于类型是明确的,因此我们可以交由编译器来推断类型数组的类型:
Box-sizing: border-Box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: "Source Code Pro",monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;"><span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">var</span> shoppingList = [<span class="hljs-string" style="color: rgb(0,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li></ul>
访问和修改数组(Accessing And Modifying An Array)
常见的数组访问和修改操作有:
- 获取数组元素个数
- 判断数组是否为空
- 数组追加元素
- 数组在某个位置插入元素
- 数组在某个范围插入元素
数组元素个数
数组判断是否为空
判断数组是否为空,可以通过isEmpty
属性判断,也可以通过count
判断:
数组末尾追加元素
常用的有以下几种方法:
- 通过
append()
追加 - 通过
appendContentsOf()
追加 - 通过
+=
追加
我们先来分析一下数组结构体所提供的方法:
Box-sizing: border-Box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: "Source Code Pro",0); Box-sizing: border-Box;"><span class="hljs-xmlDocTag" style="Box-sizing: border-Box;">///</span> Append the elements of `newElements` to `self`.</span> <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;">///</span> <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;"><span class="hljs-xmlDocTag" style="Box-sizing: border-Box;">///</span> - Complexity: O(*length of result*).</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">public</span> mutating func appendContentsOf<S : SequenceType <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">where</span> S.Generator.Element == Element>(newElements: S) <span class="hljs-comment" style="color: rgb(136,136); Box-sizing: border-Box;">public</span> mutating func appendContentsOf<C : CollectionType <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">where</span> C.Generator.Element == Element>(newElements: C)</code><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li><li style="Box-sizing: border-Box; padding: 0px 5px;">4</li><li style="Box-sizing: border-Box; padding: 0px 5px;">5</li><li style="Box-sizing: border-Box; padding: 0px 5px;">6</li><li style="Box-sizing: border-Box; padding: 0px 5px;">7</li><li style="Box-sizing: border-Box; padding: 0px 5px;">8</li></ul><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li><li style="Box-sizing: border-Box; padding: 0px 5px;">4</li><li style="Box-sizing: border-Box; padding: 0px 5px;">5</li><li style="Box-sizing: border-Box; padding: 0px 5px;">6</li><li style="Box-sizing: border-Box; padding: 0px 5px;">7</li><li style="Box-sizing: border-Box; padding: 0px 5px;">8</li></ul>
我们可以看到对于第一个appendContentsOf
方法要求参数S
是遵守了SequenceType
:
Box-sizing: border-Box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: "Source Code Pro",136); Box-sizing: border-Box;">var</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">array</span> = [<span class="hljs-number" style="color: rgb(0,102); Box-sizing: border-Box;">1</span>,<span class="hljs-number" style="color: rgb(0,102); Box-sizing: border-Box;">2</span>] <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;">// 追加单个元素</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">array</span>.append(<span class="hljs-number" style="color: rgb(0,102); Box-sizing: border-Box;">3</span>) <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;">// 追加一个数组</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">array</span> += [<span class="hljs-number" style="color: rgb(0,102); Box-sizing: border-Box;">4</span>,102); Box-sizing: border-Box;">5</span>] <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;">// 追加一个集合</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">array</span>.appendContentsOf([<span class="hljs-number" style="color: rgb(0,102); Box-sizing: border-Box;">6</span>,102); Box-sizing: border-Box;">7</span>]) <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;">// 追加一个序列:1,2,3,4,5,6</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">array</span>.appendContentsOf(<span class="hljs-number" style="color: rgb(0,102); Box-sizing: border-Box;">1.</span>.<span class="hljs-number" style="color: rgb(0,102); Box-sizing: border-Box;">.6</span>)</code><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li><li style="Box-sizing: border-Box; padding: 0px 5px;">4</li><li style="Box-sizing: border-Box; padding: 0px 5px;">5</li><li style="Box-sizing: border-Box; padding: 0px 5px;">6</li><li style="Box-sizing: border-Box; padding: 0px 5px;">7</li><li style="Box-sizing: border-Box; padding: 0px 5px;">8</li><li style="Box-sizing: border-Box; padding: 0px 5px;">9</li><li style="Box-sizing: border-Box; padding: 0px 5px;">10</li><li style="Box-sizing: border-Box; padding: 0px 5px;">11</li><li style="Box-sizing: border-Box; padding: 0px 5px;">12</li><li style="Box-sizing: border-Box; padding: 0px 5px;">13</li></ul><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li><li style="Box-sizing: border-Box; padding: 0px 5px;">4</li><li style="Box-sizing: border-Box; padding: 0px 5px;">5</li><li style="Box-sizing: border-Box; padding: 0px 5px;">6</li><li style="Box-sizing: border-Box; padding: 0px 5px;">7</li><li style="Box-sizing: border-Box; padding: 0px 5px;">8</li><li style="Box-sizing: border-Box; padding: 0px 5px;">9</li><li style="Box-sizing: border-Box; padding: 0px 5px;">10</li><li style="Box-sizing: border-Box; padding: 0px 5px;">11</li><li style="Box-sizing: border-Box; padding: 0px 5px;">12</li><li style="Box-sizing: border-Box; padding: 0px 5px;">13</li></ul>
数组插入元素
数组提供了insert(_:at:)
方法插入数据:
那么可以通过调用来插入数据:
Box-sizing: border-Box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: "Source Code Pro",102); Box-sizing: border-Box;">2</span>] <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">array</span>.insert(<span class="hljs-number" style="color: rgb(0,102); Box-sizing: border-Box;">55</span>,atIndex: <span class="hljs-number" style="color: rgb(0,102); Box-sizing: border-Box;">2</span>)</code><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li></ul>
数组修改值
@H_403_145@<code class="hljs coffeescript has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; Box-sizing: border-Box; font-family: "Source Code Pro",monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;"><span class="hljs-regexp" style="color: rgb(0,0); Box-sizing: border-Box;">//</span> 这个方法是在index位置插入数据或者获取index位置的数据 public subscript <span class="hljs-function" style="Box-sizing: border-Box;"><span class="hljs-params" style="color: rgb(102,102); Box-sizing: border-Box;">(index: Int)</span> -></span> Element <span class="hljs-regexp" style="color: rgb(0,0); Box-sizing: border-Box;">//</span> 这个方法是在指定的range插入多个数据或者获取指定range的数据 public subscript <span class="hljs-function" style="Box-sizing: border-Box;"><span class="hljs-params" style="color: rgb(102,102); Box-sizing: border-Box;">(subRange: Range<Int>)</span> -></span> ArraySlice<Element></code><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li><li style="Box-sizing: border-Box; padding: 0px 5px;">4</li><li style="Box-sizing: border-Box; padding: 0px 5px;">5</li></ul>Box-sizing: border-Box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: "Source Code Pro",0); Box-sizing: border-Box;">// 修改元素值,可以通过索引</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">array</span>[<span class="hljs-number" style="color: rgb(0,102); Box-sizing: border-Box;">0</span>] = <span class="hljs-number" style="color: rgb(0,102); Box-sizing: border-Box;">100</span> <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;">// 获取</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">print</span>(<span class="hljs-keyword" style="color: rgb(0,102); Box-sizing: border-Box;">0</span>]) <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;">// 可以修改指定范围的值</span> <span class="hljs-keyword" style="color: rgb(0,102); Box-sizing: border-Box;">1.</span>.<<span class="hljs-number" style="color: rgb(0,102); Box-sizing: border-Box;">4</span>] = [<span class="hljs-number" style="color: rgb(0,102); Box-sizing: border-Box;">77</span>,102); Box-sizing: border-Box;">88</span>,102); Box-sizing: border-Box;">99</span>] <span class="hljs-comment" style="color: rgb(136,102); Box-sizing: border-Box;">4</span>])</code><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li><li style="Box-sizing: border-Box; padding: 0px 5px;">4</li><li style="Box-sizing: border-Box; padding: 0px 5px;">5</li><li style="Box-sizing: border-Box; padding: 0px 5px;">6</li><li style="Box-sizing: border-Box; padding: 0px 5px;">7</li><li style="Box-sizing: border-Box; padding: 0px 5px;">8</li><li style="Box-sizing: border-Box; padding: 0px 5px;">9</li></ul>
也可以调用replaceRange(_:with:)
来替换值:
数组移除元素
先看看苹果所提供的方法:
看看如何调用:
数组遍历
常用的数组遍历有几种。
第一种,只获取元素值的for-in遍历:
第二种,获取元素及索引的for-in遍历:
Box-sizing: border-Box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: "Source Code Pro",136); Box-sizing: border-Box;">for</span> (index,136); Box-sizing: border-Box;">value</span>) <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">in</span> <span class="hljs-built_in" style="color: rgb(102,102); Box-sizing: border-Box;">array</span>.enumerate() { print(<span class="hljs-string" style="color: rgb(0,0); Box-sizing: border-Box;">"index: \(index),value = \(value)"</span>) }</code><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li></ul>
集合(Sets)
集合(Set)用来存储相同类型并且没有确定顺序的值。当集合元素顺序不重要时或者希望确保每个元素只出现一次时可以使用集合而不是数组。
为了存储在集合中,该类型必须是可哈希化的。也就是说,该类型必须提供一个方法来计算它的哈希值。一个哈希值是Int类型的,它和其他的对象相同,其被用来比较相等与否,比如a==b,它遵循的是a.hashValue == b.hashValue。Swift 的所有基本类型(比如String,Int,Double和Bool)默认都是可哈希化的,它可以作为集合的值或者字典的键值类型。没有关联值的枚举成员值(在枚举有讲述)默认也是可哈希化的。
使用自定义的类型作为集合的值或者是字典的键值类型时,需要使自定义类型服从Swift标准库中的Hashable协议。服从Hashable协议的类型需要提供一个类型为Int的取值访问器属性hashValue。这个由类型的hashValue返回的值不需要在同一程序的不同执行周期或者不同程序之间保持相同。 因为hashable协议服从于Equatable协议,所以遵循该协议的类型也必须提供一个”是否等”运算符(\==)的实现。这个Equatable协议需要任何遵循的\==的实现都是一种相等的关系。也就是说,对于a,b,c三个值来说,\==的实现必须满足下面三种情况:
- a\==a(自反性)
- a\==b 可推出 b\==a(对称性)
- a\==b&&b\==c 可推出 a\==c(传递性)
空集合(Empty Set)
Swift
中的Set
类型被写为Set<Element>
,这里的Element
表示Set
中允许存储的类型,和数组不同的是,集合没有等价的简化形式。
Box-sizing: border-Box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: "Source Code Pro",136); Box-sizing: border-Box;">var</span> emptySet = Set<Int>() <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">print</span>(emptySet.count) <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;">// 0</span> <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;">// 当变量已经有明确的类型时,再用空数组来初始化[],其类型也是可推断的</span> emptySet = []<span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;">// 类型为Set<Int>()</span></code><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li><li style="Box-sizing: border-Box; padding: 0px 5px;">4</li><li style="Box-sizing: border-Box; padding: 0px 5px;">5</li></ul>
初始化集合(Initializing An Empty Set)
可以直接使用数组字面量来初始化集合:
Box-sizing: border-Box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: "Source Code Pro",0); Box-sizing: border-Box;">// 用数组构造集合</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">var</span> favSet: Set<<span class="hljs-built_in" style="color: rgb(102,102); Box-sizing: border-Box;">String</span>> = [<span class="hljs-string" style="color: rgb(0,0); Box-sizing: border-Box;">"milk"</span>,0); Box-sizing: border-Box;">"egg"</span>] <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;">// 如果元素都是相同类型,带有初始化,可以省略类型</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">var</span> favSet1: Set = [<span class="hljs-string" style="color: rgb(0,0); Box-sizing: border-Box;">"good milk"</span>,0); Box-sizing: border-Box;">"bad egg"</span>]</code><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li><li style="Box-sizing: border-Box; padding: 0px 5px;">4</li><li style="Box-sizing: border-Box; padding: 0px 5px;">5</li></ul>
使用集合可以非常好地解决重复问题:
Box-sizing: border-Box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: "Source Code Pro",0); Box-sizing: border-Box;">// 重复的数据会被自动去重</span> <span class="hljs-keyword" style="color: rgb(0,0); Box-sizing: border-Box;">"egg"</span>,0); Box-sizing: border-Box;">"milk"</span>] print(favSet.count)<span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;">// 2</span></code><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li></ul>
访问集合(Accessing A Set)
获取集合元素的个数,可以通过count
只读属性获取,其时间复杂度为O(1),也就是常量,因此效率是极高的。想想时间复杂度能达到O(1),说明内部并不是列表,而是类似字典那样的哈希表,不过具体内部是如何,这里不细说,还得去查看源代码才能知晓。
Box-sizing: border-Box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: "Source Code Pro",0); Box-sizing: border-Box;"><span class="hljs-xmlDocTag" style="Box-sizing: border-Box;">///</span> The number of members in the set.</span> <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;"><span class="hljs-xmlDocTag" style="Box-sizing: border-Box;">///</span> - Complexity: O(1).</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">public</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">var</span> count: Int { <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">get</span> }</code><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li><li style="Box-sizing: border-Box; padding: 0px 5px;">4</li></ul><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li><li style="Box-sizing: border-Box; padding: 0px 5px;">4</li></ul>
调用就很方便了,效率又非常地高:
我们还可以通过isEmpty
属性判断是否为空:
Box-sizing: border-Box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: "Source Code Pro",0); Box-sizing: border-Box;">// 官方声明如下:</span> <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;"><span class="hljs-xmlDocTag" style="Box-sizing: border-Box;">///</span> `true` if the set is empty.</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">var</span> isEmpty: Bool { <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">get</span> } <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;">// 判断是否为空集</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">if</span> favSet.isEmpty { print(<span class="hljs-string" style="color: rgb(0,0); Box-sizing: border-Box;">"empty set"</span>) } <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">else</span> { print(<span class="hljs-string" style="color: rgb(0,0); Box-sizing: border-Box;">"non empty set"</span>) }</code><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li><li style="Box-sizing: border-Box; padding: 0px 5px;">4</li><li style="Box-sizing: border-Box; padding: 0px 5px;">5</li><li style="Box-sizing: border-Box; padding: 0px 5px;">6</li><li style="Box-sizing: border-Box; padding: 0px 5px;">7</li><li style="Box-sizing: border-Box; padding: 0px 5px;">8</li><li style="Box-sizing: border-Box; padding: 0px 5px;">9</li><li style="Box-sizing: border-Box; padding: 0px 5px;">10</li></ul><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li><li style="Box-sizing: border-Box; padding: 0px 5px;">4</li><li style="Box-sizing: border-Box; padding: 0px 5px;">5</li><li style="Box-sizing: border-Box; padding: 0px 5px;">6</li><li style="Box-sizing: border-Box; padding: 0px 5px;">7</li><li style="Box-sizing: border-Box; padding: 0px 5px;">8</li><li style="Box-sizing: border-Box; padding: 0px 5px;">9</li><li style="Box-sizing: border-Box; padding: 0px 5px;">10</li></ul>
判断元素是否在集合中:
Box-sizing: border-Box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: "Source Code Pro",0); Box-sizing: border-Box;">// 判断是否包含元素</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">if</span> favSet.contains(<span class="hljs-string" style="color: rgb(0,0); Box-sizing: border-Box;">"wahaha"</span>) { <span class="hljs-keyword" style="color: rgb(0,0); Box-sizing: border-Box;">"fav set contains wahaha"</span>) } <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">else</span> { <span class="hljs-keyword" style="color: rgb(0,0); Box-sizing: border-Box;">"fav set doesn\'t not contain wahaha"</span>) }</code><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li><li style="Box-sizing: border-Box; padding: 0px 5px;">4</li><li style="Box-sizing: border-Box; padding: 0px 5px;">5</li><li style="Box-sizing: border-Box; padding: 0px 5px;">6</li></ul>
遍历集合(Iterating Over A Set)
遍历很少能离开得了for-in
语法:
Box-sizing: border-Box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: "Source Code Pro",monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;">// 遍历一个<span class="hljs-built_in" style="color: rgb(102,102); Box-sizing: border-Box;">set</span>。使用<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">for</span>-<span class="hljs-operator" style="Box-sizing: border-Box;">in</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">for</span> <span class="hljs-built_in" style="color: rgb(102,102); Box-sizing: border-Box;">value</span> <span class="hljs-operator" style="Box-sizing: border-Box;">in</span> favSet { print(<span class="hljs-built_in" style="color: rgb(102,102); Box-sizing: border-Box;">value</span><span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;">)// 这是无序的</span> }</code><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li><li style="Box-sizing: border-Box; padding: 0px 5px;">4</li></ul>
遍历集合,同时使集合是有序的:
Box-sizing: border-Box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: "Source Code Pro",monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;">// 要使之有序<span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;"> // sort方法</span> <span class="hljs-keyword" style="color: rgb(0,102); Box-sizing: border-Box;">value</span> <span class="hljs-operator" style="Box-sizing: border-Box;">in</span> favSet.<span class="hljs-built_in" style="color: rgb(102,102); Box-sizing: border-Box;">sort</span>({ (e,ee) -> Bool <span class="hljs-operator" style="Box-sizing: border-Box;">in</span> <span class="hljs-constant" style="Box-sizing: border-Box;">return</span> e > ee<span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;"> // 由我们指定排序类型desc(降序)</span> }) { <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;"> // milk</span> <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;"> // egg</span> print(<span class="hljs-built_in" style="color: rgb(102,102); Box-sizing: border-Box;">value</span>) } <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;"> // 或者:</span><span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;"> // 或者直接使用sort无参数(默认为asc升序)</span> <span class="hljs-keyword" style="color: rgb(0,102); Box-sizing: border-Box;">sort</span>() { <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;"> // egg</span> <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;"> // milk</span> print(<span class="hljs-built_in" style="color: rgb(102,102); Box-sizing: border-Box;">value</span>) }</code><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li><li style="Box-sizing: border-Box; padding: 0px 5px;">4</li><li style="Box-sizing: border-Box; padding: 0px 5px;">5</li><li style="Box-sizing: border-Box; padding: 0px 5px;">6</li><li style="Box-sizing: border-Box; padding: 0px 5px;">7</li><li style="Box-sizing: border-Box; padding: 0px 5px;">8</li><li style="Box-sizing: border-Box; padding: 0px 5px;">9</li><li style="Box-sizing: border-Box; padding: 0px 5px;">10</li><li style="Box-sizing: border-Box; padding: 0px 5px;">11</li><li style="Box-sizing: border-Box; padding: 0px 5px;">12</li><li style="Box-sizing: border-Box; padding: 0px 5px;">13</li><li style="Box-sizing: border-Box; padding: 0px 5px;">14</li><li style="Box-sizing: border-Box; padding: 0px 5px;">15</li><li style="Box-sizing: border-Box; padding: 0px 5px;">16</li><li style="Box-sizing: border-Box; padding: 0px 5px;">17</li></ul>
当然还可以使用最原始的方法来遍历:
集合基本操作(Fundamental Set Operations)
集合的基本操作有:
- 求交集:使用intersect(_:)方法根据两个集合中都包含的值创建的一个新的集合。
- 求非交集:使用exclusiveOr(_:)方法根据在一个集合中但不在两个集合中的值创建一个新的集合。
- 求并集:使用union(_:)方法根据两个集合的值创建一个新的集合。
- 求差集:使用subtract(_:)方法根据不在该集合中的值创建一个新的集合。
集合成员关系(Relationships Of Set members)
- 使用\==来判断两个集合是否包含全部相同的值。
- 使用isSubsetOf(_:)方法来判断是否为子集
- 使用isSupersetOf(_:)方法来判断是否为超集
- 使用isStrictSubsetOf(_:)或者isStrictSupersetOf(_:)方法来判断一个集合是否是另外一个集合的子集合或者父集合并且两个集合并不相等。
- 使用isDisjointWith(_:)方法来判断两个集合是否不含有相同的值。
从图中可以看出:
- 集合a全部包含b,也就是说b是a的子集
- 集合a与集合b相交,但是a与b不完全包含
- 集合c与集合b完全没有交集
Box-sizing: border-Box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: "Source Code Pro",102); Box-sizing: border-Box;">8</span>] // <span class="hljs-literal" style="color: rgb(0,102); Box-sizing: border-Box;">false</span> // <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>1并没有全部被<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>2包含 print(<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>1.isSubsetOf(<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>2)) <span class="hljs-built_in" style="color: rgb(102,136); Box-sizing: border-Box;">set</span>3: Set = [<span class="hljs-number" style="color: rgb(0,102); Box-sizing: border-Box;">5</span>] // <span class="hljs-literal" style="color: rgb(0,102); Box-sizing: border-Box;">true</span> // <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>3全部在<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>1中 print(<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>3.isSubsetOf(<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>1)) // <span class="hljs-literal" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>1真包含<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>3,因此<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>1是<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>3的超集 print(<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>1.isSupersetOf(<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>3)) // <span class="hljs-literal" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>3的严格超集,因为Set1真包含<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>3且<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>1 != <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>3 print(<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>1.isStrictSupersetOf(<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>3,且<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>3是<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>1严格的真子集 print(<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>3.isStrictSubsetOf(<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>1)) <span class="hljs-built_in" style="color: rgb(102,136); Box-sizing: border-Box;">set</span>4: Set = [<span class="hljs-number" style="color: rgb(0,102); Box-sizing: border-Box;">2</span>] // <span class="hljs-literal" style="color: rgb(0,102); Box-sizing: border-Box;">false</span> // 因为<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>3和<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>4的元素是一样的,即相等 print(<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>4.isStrictSubsetOf(<span class="hljs-keyword" style="color: rgb(0,102); Box-sizing: border-Box;">false</span> // 这两个集合中有相同的元素 print(<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>3.isDisjointWith(<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>4)) <span class="hljs-built_in" style="color: rgb(102,136); Box-sizing: border-Box;">set</span>5:Set = [<span class="hljs-number" style="color: rgb(0,102); Box-sizing: border-Box;">9</span>,102); Box-sizing: border-Box;">6</span>] // <span class="hljs-literal" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>5和<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>4没有相同的元素 print(<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>5.isDisjointWith(<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">set</span>4))</code><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li><li style="Box-sizing: border-Box; padding: 0px 5px;">4</li><li style="Box-sizing: border-Box; padding: 0px 5px;">5</li><li style="Box-sizing: border-Box; padding: 0px 5px;">6</li><li style="Box-sizing: border-Box; padding: 0px 5px;">7</li><li style="Box-sizing: border-Box; padding: 0px 5px;">8</li><li style="Box-sizing: border-Box; padding: 0px 5px;">9</li><li style="Box-sizing: border-Box; padding: 0px 5px;">10</li><li style="Box-sizing: border-Box; padding: 0px 5px;">11</li><li style="Box-sizing: border-Box; padding: 0px 5px;">12</li><li style="Box-sizing: border-Box; padding: 0px 5px;">13</li><li style="Box-sizing: border-Box; padding: 0px 5px;">14</li><li style="Box-sizing: border-Box; padding: 0px 5px;">15</li><li style="Box-sizing: border-Box; padding: 0px 5px;">16</li><li style="Box-sizing: border-Box; padding: 0px 5px;">17</li><li style="Box-sizing: border-Box; padding: 0px 5px;">18</li><li style="Box-sizing: border-Box; padding: 0px 5px;">19</li><li style="Box-sizing: border-Box; padding: 0px 5px;">20</li><li style="Box-sizing: border-Box; padding: 0px 5px;">21</li><li style="Box-sizing: border-Box; padding: 0px 5px;">22</li><li style="Box-sizing: border-Box; padding: 0px 5px;">23</li><li style="Box-sizing: border-Box; padding: 0px 5px;">24</li><li style="Box-sizing: border-Box; padding: 0px 5px;">25</li><li style="Box-sizing: border-Box; padding: 0px 5px;">26</li><li style="Box-sizing: border-Box; padding: 0px 5px;">27</li><li style="Box-sizing: border-Box; padding: 0px 5px;">28</li><li style="Box-sizing: border-Box; padding: 0px 5px;">29</li><li style="Box-sizing: border-Box; padding: 0px 5px;">30</li><li style="Box-sizing: border-Box; padding: 0px 5px;">31</li><li style="Box-sizing: border-Box; padding: 0px 5px;">32</li><li style="Box-sizing: border-Box; padding: 0px 5px;">33</li><li style="Box-sizing: border-Box; padding: 0px 5px;">34</li><li style="Box-sizing: border-Box; padding: 0px 5px;">35</li><li style="Box-sizing: border-Box; padding: 0px 5px;">36</li><li style="Box-sizing: border-Box; padding: 0px 5px;">37</li><li style="Box-sizing: border-Box; padding: 0px 5px;">38</li><li style="Box-sizing: border-Box; padding: 0px 5px;">39</li><li style="Box-sizing: border-Box; padding: 0px 5px;">40</li></ul><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li><li style="Box-sizing: border-Box; padding: 0px 5px;">4</li><li style="Box-sizing: border-Box; padding: 0px 5px;">5</li><li style="Box-sizing: border-Box; padding: 0px 5px;">6</li><li style="Box-sizing: border-Box; padding: 0px 5px;">7</li><li style="Box-sizing: border-Box; padding: 0px 5px;">8</li><li style="Box-sizing: border-Box; padding: 0px 5px;">9</li><li style="Box-sizing: border-Box; padding: 0px 5px;">10</li><li style="Box-sizing: border-Box; padding: 0px 5px;">11</li><li style="Box-sizing: border-Box; padding: 0px 5px;">12</li><li style="Box-sizing: border-Box; padding: 0px 5px;">13</li><li style="Box-sizing: border-Box; padding: 0px 5px;">14</li><li style="Box-sizing: border-Box; padding: 0px 5px;">15</li><li style="Box-sizing: border-Box; padding: 0px 5px;">16</li><li style="Box-sizing: border-Box; padding: 0px 5px;">17</li><li style="Box-sizing: border-Box; padding: 0px 5px;">18</li><li style="Box-sizing: border-Box; padding: 0px 5px;">19</li><li style="Box-sizing: border-Box; padding: 0px 5px;">20</li><li style="Box-sizing: border-Box; padding: 0px 5px;">21</li><li style="Box-sizing: border-Box; padding: 0px 5px;">22</li><li style="Box-sizing: border-Box; padding: 0px 5px;">23</li><li style="Box-sizing: border-Box; padding: 0px 5px;">24</li><li style="Box-sizing: border-Box; padding: 0px 5px;">25</li><li style="Box-sizing: border-Box; padding: 0px 5px;">26</li><li style="Box-sizing: border-Box; padding: 0px 5px;">27</li><li style="Box-sizing: border-Box; padding: 0px 5px;">28</li><li style="Box-sizing: border-Box; padding: 0px 5px;">29</li><li style="Box-sizing: border-Box; padding: 0px 5px;">30</li><li style="Box-sizing: border-Box; padding: 0px 5px;">31</li><li style="Box-sizing: border-Box; padding: 0px 5px;">32</li><li style="Box-sizing: border-Box; padding: 0px 5px;">33</li><li style="Box-sizing: border-Box; padding: 0px 5px;">34</li><li style="Box-sizing: border-Box; padding: 0px 5px;">35</li><li style="Box-sizing: border-Box; padding: 0px 5px;">36</li><li style="Box-sizing: border-Box; padding: 0px 5px;">37</li><li style="Box-sizing: border-Box; padding: 0px 5px;">38</li><li style="Box-sizing: border-Box; padding: 0px 5px;">39</li><li style="Box-sizing: border-Box; padding: 0px 5px;">40</li></ul>
字典(Dictonaries)
字典是一种存储多个相同类型的值的容器。每个值都关联唯一的键,键作为字典中的这个值数据的标识符。和数组中的数据项不同,字典中的数据项并没有顺序的。我们在需要通过key访问数据的时候使用字典,这种方法很大程度上和我们在现实世界中使用字典查字义的方法一样。
Swift中的Dictionary与Foundation中的NSDictionary是桥接的,可以互相转换使用。
我们先来看看字典的结构定义:
40452" class="prettyprint" name="code" style="white-space: nowrap; word-wrap: break-word; Box-sizing: border-Box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: "Source Code Pro",0); Box-sizing: border-Box;"><span class="hljs-xmlDocTag" style="Box-sizing: border-Box;">///</span> A hash-based mapping from `Key` to `Value` instances. Also a</span> <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;"><span class="hljs-xmlDocTag" style="Box-sizing: border-Box;">///</span> collection of key-value pairs with no defined ordering.</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">struct</span> Dictionary<Key : Hashable,Value> : CollectionType,DictionaryLiteralConvertible</code><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li></ul>
它是基于哈希表从key到value实例的映射,它的键值是无序的。要求key是遵守Hashable的。
其正规语法应该是:Dictonary<key,value>
。
创建空字典(Creating An Empty Dictionary)
Box-sizing: border-Box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: "Source Code Pro",0); Box-sizing: border-Box;">// 创建空字典</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">var</span> emptyDict = [Int: <span class="hljs-built_in" style="color: rgb(102,102); Box-sizing: border-Box;">String</span>]() <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;">// 或者</span> emptyDict = Dictionary<Int,<span class="hljs-built_in" style="color: rgb(102,102); Box-sizing: border-Box;">String</span>>() <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;">// 当创建过emptyDict后,再用[:]又成为一个空字典</span> emptyDict = [:]</code><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li><li style="Box-sizing: border-Box; padding: 0px 5px;">4</li><li style="Box-sizing: border-Box; padding: 0px 5px;">5</li><li style="Box-sizing: border-Box; padding: 0px 5px;">6</li><li style="Box-sizing: border-Box; padding: 0px 5px;">7</li><li style="Box-sizing: border-Box; padding: 0px 5px;">8</li></ul>
初始化字典(Initializing A Dictionary)
Box-sizing: border-Box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: "Source Code Pro",0); Box-sizing: border-Box;">// 多个键值对用逗号分割</span> <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;">// 通过类型推断是可以推断出来类型为[String: String]</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">var</span> dict = [<span class="hljs-string" style="color: rgb(0,0); Box-sizing: border-Box;">"A"</span>: <span class="hljs-string" style="color: rgb(0,0); Box-sizing: border-Box;">"Apple"</span>,0); Box-sizing: border-Box;">"B"</span>: <span class="hljs-string" style="color: rgb(0,0); Box-sizing: border-Box;">"Bubble"</span>] <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;">// 手动指明数据类型</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">var</span> airports: [<span class="hljs-built_in" style="color: rgb(102,102); Box-sizing: border-Box;">String</span>: <span class="hljs-built_in" style="color: rgb(102,0); Box-sizing: border-Box;">"YYZ"</span>: <span class="hljs-string" style="color: rgb(0,0); Box-sizing: border-Box;">"Toronto Pearson"</span>,0); Box-sizing: border-Box;">"DUB"</span>: <span class="hljs-string" style="color: rgb(0,0); Box-sizing: border-Box;">"Dublin"</span>]</code><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li><li style="Box-sizing: border-Box; padding: 0px 5px;">4</li><li style="Box-sizing: border-Box; padding: 0px 5px;">5</li><li style="Box-sizing: border-Box; padding: 0px 5px;">6</li></ul>
声明不可变字典:
Box-sizing: border-Box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: "Source Code Pro",monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;">// 如果不希望字典可变,用<span class="hljs-built_in" style="color: rgb(102,102); Box-sizing: border-Box;">let</span>声明即可 <span class="hljs-built_in" style="color: rgb(102,102); Box-sizing: border-Box;">let</span> immutableDict = [<span class="hljs-string" style="color: rgb(0,0); Box-sizing: border-Box;">"Bubble"</span>] // 无法调用,因为是不可变的 //immutableDict.updateValue(<span class="hljs-string" style="color: rgb(0,0); Box-sizing: border-Box;">"App"</span>,136); Box-sizing: border-Box;">for</span>Key: <span class="hljs-string" style="color: rgb(0,0); Box-sizing: border-Box;">"A"</span>) //immutableDict += [<span class="hljs-string" style="color: rgb(0,0); Box-sizing: border-Box;">"AB:"</span>,0); Box-sizing: border-Box;">"Apple Bubble"</span>]</code><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li><li style="Box-sizing: border-Box; padding: 0px 5px;">4</li><li style="Box-sizing: border-Box; padding: 0px 5px;">5</li></ul>
访问和修改字典(Accessing And Modifying A Dictionary)
我们可以通过字典的方法和属性来访问和修改字典,或者通过使用下标语法。
判断是否为空字典:
Box-sizing: border-Box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: "Source Code Pro",136); Box-sizing: border-Box;">if</span> dict.isEmpty { <span class="hljs-keyword" style="color: rgb(0,0); Box-sizing: border-Box;">"dict is an empty dictionary"</span>) } <span class="hljs-keyword" style="color: rgb(0,0); Box-sizing: border-Box;">"dict is not an empty dictionary"</span>) } <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;">// 或者通过获取字典元素的个数是否为0</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">if</span> dict.count == <span class="hljs-number" style="color: rgb(0,102); Box-sizing: border-Box;">0</span> { <span class="hljs-keyword" style="color: rgb(0,0); Box-sizing: border-Box;">"dict is not an empty dictionary"</span>) }</code><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li><li style="Box-sizing: border-Box; padding: 0px 5px;">4</li><li style="Box-sizing: border-Box; padding: 0px 5px;">5</li><li style="Box-sizing: border-Box; padding: 0px 5px;">6</li><li style="Box-sizing: border-Box; padding: 0px 5px;">7</li><li style="Box-sizing: border-Box; padding: 0px 5px;">8</li><li style="Box-sizing: border-Box; padding: 0px 5px;">9</li><li style="Box-sizing: border-Box; padding: 0px 5px;">10</li><li style="Box-sizing: border-Box; padding: 0px 5px;">11</li><li style="Box-sizing: border-Box; padding: 0px 5px;">12</li></ul>
可以直接通过下标获取元素:
Box-sizing: border-Box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: "Source Code Pro",0); Box-sizing: border-Box;">// 通过key直接获取</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">var</span> apple = dict[<span class="hljs-string" style="color: rgb(0,0); Box-sizing: border-Box;">"A"</span>] <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;">// 获取索引获取(key,value),再获取值</span> <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;">// 由于字典中的(key,value)是元组,因此可以直接通过点语法获取</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">let</span> startKeyValue = dict[dict.startIndex] <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">let</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">value</span> = startKeyValue<span class="hljs-number" style="color: rgb(0,102); Box-sizing: border-Box;">.1</span> <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;">// 读取时,判断是否有值</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">if</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">value</span> = dict[<span class="hljs-string" style="color: rgb(0,0); Box-sizing: border-Box;">"BB"</span>] { print(<span class="hljs-string" style="color: rgb(0,0); Box-sizing: border-Box;">"value is \(value)"</span>) } <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">else</span> { <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;">// 输入这行</span> print(<span class="hljs-string" style="color: rgb(0,0); Box-sizing: border-Box;">"The key BB doesn\'t not exist in dict"</span>) }</code><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li><li style="Box-sizing: border-Box; padding: 0px 5px;">4</li><li style="Box-sizing: border-Box; padding: 0px 5px;">5</li><li style="Box-sizing: border-Box; padding: 0px 5px;">6</li><li style="Box-sizing: border-Box; padding: 0px 5px;">7</li><li style="Box-sizing: border-Box; padding: 0px 5px;">8</li><li style="Box-sizing: border-Box; padding: 0px 5px;">9</li><li style="Box-sizing: border-Box; padding: 0px 5px;">10</li><li style="Box-sizing: border-Box; padding: 0px 5px;">11</li><li style="Box-sizing: border-Box; padding: 0px 5px;">12</li><li style="Box-sizing: border-Box; padding: 0px 5px;">13</li><li style="Box-sizing: border-Box; padding: 0px 5px;">14</li><li style="Box-sizing: border-Box; padding: 0px 5px;">15</li></ul><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li><li style="Box-sizing: border-Box; padding: 0px 5px;">4</li><li style="Box-sizing: border-Box; padding: 0px 5px;">5</li><li style="Box-sizing: border-Box; padding: 0px 5px;">6</li><li style="Box-sizing: border-Box; padding: 0px 5px;">7</li><li style="Box-sizing: border-Box; padding: 0px 5px;">8</li><li style="Box-sizing: border-Box; padding: 0px 5px;">9</li><li style="Box-sizing: border-Box; padding: 0px 5px;">10</li><li style="Box-sizing: border-Box; padding: 0px 5px;">11</li><li style="Box-sizing: border-Box; padding: 0px 5px;">12</li><li style="Box-sizing: border-Box; padding: 0px 5px;">13</li><li style="Box-sizing: border-Box; padding: 0px 5px;">14</li><li style="Box-sizing: border-Box; padding: 0px 5px;">15</li></ul>
Box-sizing: border-Box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: "Source Code Pro",0); Box-sizing: border-Box;">// 修改,如果不存在,则会增加,否则更新值</span> dict[<span class="hljs-string" style="color: rgb(0,0); Box-sizing: border-Box;">"A"</span>] = <span class="hljs-string" style="color: rgb(0,0); Box-sizing: border-Box;">"Good Apple"</span> <span class="hljs-comment" style="color: rgb(136,0); Box-sizing: border-Box;">// 或者用API,如果不存在,则会增加,否则只是更新值</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">if</span> let oldValue = dict.updateValue(<span class="hljs-string" style="color: rgb(0,0); Box-sizing: border-Box;">"Dog"</span>,forKey: <span class="hljs-string" style="color: rgb(0,0); Box-sizing: border-Box;">"D"</span>) { <span class="hljs-keyword" style="color: rgb(0,0); Box-sizing: border-Box;">"The old value is \(oldValue)"</span>) } <span class="hljs-keyword" style="color: rgb(0,0); Box-sizing: border-Box;">// 输出这行</span> <span class="hljs-keyword" style="color: rgb(0,0); Box-sizing: border-Box;">"The key D does\'t not exist before update"</span>) }</code><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li><li style="Box-sizing: border-Box; padding: 0px 5px;">4</li><li style="Box-sizing: border-Box; padding: 0px 5px;">5</li><li style="Box-sizing: border-Box; padding: 0px 5px;">6</li><li style="Box-sizing: border-Box; padding: 0px 5px;">7</li><li style="Box-sizing: border-Box; padding: 0px 5px;">8</li><li style="Box-sizing: border-Box; padding: 0px 5px;">9</li><li style="Box-sizing: border-Box; padding: 0px 5px;">10</li></ul>
移除元素:
字典遍历(Iterate Over A Dictionary)
字典中每个元素是一个键值对,而这个键值对其实就是一个元组:
Box-sizing: border-Box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: "Source Code Pro",monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;">// 用<span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">for</span>-<span class="hljs-operator" style="Box-sizing: border-Box;">in</span>遍历,形式为(key,102); Box-sizing: border-Box;">value</span>) <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">for</span> (key,102); Box-sizing: border-Box;">value</span>) <span class="hljs-operator" style="Box-sizing: border-Box;">in</span> dict { print(<span class="hljs-string" style="color: rgb(0,0); Box-sizing: border-Box;">"\(key): \(value)"</span>) }</code><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li><li style="Box-sizing: border-Box; padding: 0px 5px;">4</li></ul>
可以通过遍历所有的key:
也可以遍历所有的值:
Box-sizing: border-Box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: "Source Code Pro",136); Box-sizing: border-Box;">value</span> <span class="hljs-keyword" style="color: rgb(0,136); Box-sizing: border-Box;">in</span> dict.values { print(<span class="hljs-string" style="color: rgb(0,0); Box-sizing: border-Box;">"\(value)"</span>) }</code><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li></ul>
字典值或者键转换成数组
如果不清楚Array有这么一个构造函数,那么您可能会手动写代码去遍历,但是事实上我们可以直接使用构造函数来实现的。我们知道字典的keys和values属性返回来的是LazyMapCollection<key,value>
类型,并不是我们直接需要到的数据,因此我们有的时候需要转换成我们直接能使用的数据,这时候就需要这么做的:
Box-sizing: border-Box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: "Source Code Pro",monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;">// 获取所有的值 let values = [<span class="hljs-link_label" style="Box-sizing: border-Box;">String</span>](<span class="hljs-link_url" style="Box-sizing: border-Box;">dict.values</span>) // 获取所有的键 let keys = [<span class="hljs-link_label" style="Box-sizing: border-Box;">String</span>](<span class="hljs-link_url" style="Box-sizing: border-Box;">dict.keys</span>)</code><ul class="pre-numbering" style="Box-sizing: border-Box; position: absolute; width: 50px; background-color: rgb(238,221); list-style: none; text-align: right;"><li style="Box-sizing: border-Box; padding: 0px 5px;">1</li><li style="Box-sizing: border-Box; padding: 0px 5px;">2</li><li style="Box-sizing: border-Box; padding: 0px 5px;">3</li><li style="Box-sizing: border-Box; padding: 0px 5px;">4</li><li style="Box-sizing: border-Box; padding: 0px 5px;">5</li></ul>