数组是一个存储多个相同类型的值的有序列表。相同的值,可以在不同的位置出现在一个数组中的多个次。
Swift数组是具体的。他不同于Objective-C的的NSArray和NSMutableArray里的类,它可以存储任何类型的对象,不提供有关它们返回的对象的性质的任何信息。在斯Swift,一个特定的数组可以存储的值类型总是明确的,无论是通过显式类型批注,或通过类型推断,而不一定是类类型。如果创建诠释值的数组,例如,你不能插入比Int值以外的任何值到该数组。Swift数组是类型安全的,并且总是清楚它们可能含有什么。
数组语法
数组的类型是Array<SomeType>,其中个SomeType是该数组允许存储的类型。你也可以写简写形式数组的类型为个SomeType[]。虽然两种形式在功能上是相同的,简写形式是首选,而指的是一个数组类型时使用本指南。
说到数组和字典,只要是编过程的小伙伴并不陌生。在Swift中的数组与字典也有着一些让人眼前一亮的特性,今天的博客就来窥探一下Swift中的Array和Dictionary。还是沿袭之前的风格,在介绍Swift中的数组时,我们会对比一下ObjC中的数组和字典,因为ObjC也是iOS开发的主要语言不是。无论是简单还是复杂的程序,数组和字典的用处还是比较多的,这两者虽然是Swift的基础内容,但是也不失其重要性。关于Objc的集合类请参考之前的博客《Objective-C中的集合类》。
一、Swift中的数组(Array)
数组在其他编程语言中都是存在的,数组就是一组数的集合。虽然其他编程语言中都有数组,但是不同语言中的数组都有着一些属于自己的特性。Swift也不例外,Swift中的数组使用起来还是比较人性化的.
1.数组的声明与创建
在聊Swift中的Array声明创建之前,我想聊一下ObjC中数组的声明与创建,下方是ObjC中不可变数组和可变数组的创建方式。在ObjC中可以使用NSArray来声明不可变数组,使用NSMutableArray来声明可变数组。
而在Swift语言中,你可以使用关键字let来声明不可变数组,使用var来声明可变数组,下方代码声明的是Swift中的可变数组的几种方式。有一点需要注意的是ObjC中的数组只允许往里面存储对象,而不允许往里存储基本数据类型(Int, Float等)。而在Swift中是允许把基本数据类型存入数组中的,如下方代码段所示。下方给出了数组的三种定义的方式。后两种给数组元素制定了数据类型,表示该数组中只能够存储Int类型的值,如果你往里存入了其他的值,对不起,编译器会报错的。
在Swift的数组中,如果在声明数组时没有指定数组中元素的数据类型,那么数组中是可以存放不同数据类型的数据的。如果你指定了数组中只允许存储一种数据类型,如果你再往里存储其他数据类型的话,那就是你的不对了,编译器回给你指出你的错误。具体如下所示:
2.数组的操作
(1)可变与不可变数组
如果你想对数组中的元素进行增加、修改或者删除,那么你需要把Array定义成可变数组。如果你把数组定义成了不可变数组,但是你又对他进行了操作,那就是你的不对了。无论是ObjC还是Swift都不允许对不可变数组这位高冷的“御姐”动手动脚,不然会抛出一个错误的。但是可变数组就不一样了,你可以对可变数组进行增删改查操作。
下图是在ObjC中对NSArray操作后的结果,你不能对NSArray中的元素进行修改,也就是说你对NSArray的操作权限只有读的权限,没有写的权限。如果你想对数组进行读写的权限的话,那你就有必要使用可变数组NSMutableArray了。使用NSMutableArray就不会报错,因为你对它有读写的权限。
在Swift中的可变数组和不可变数组归根结底还是变量和常量也就是var和let关键字的使用了。你对变量持有读写的权限,对常量持有读的权限。下方的小实例,本质还是对let和var的讨论,下方是Swift实例:
(2) 插入元素
上面Swift实例中已经展示了如何往数组中插入元素。Swift中往数组中插入元素和OC中使用的方法是一样的,只是调用方法的方式不同。下方代码就是往可变数组arrayTest中的索引1的位置插入一个值“Objc”。语法比较简单就不做过多的赘述了。
(3) 元素以及数组的追加
你可以使用append函数来往数组的尾部追加值。如果你想把另一个数组追加到一个数组的后方,你可以使用+=运算符来操作。使用+=可以连接数组,这也是Swift中令人兴奋的一个特点。具体操作请看下方的实例:
(4)移除元素
上面是添加,接下来要搞一下移除元素。其实Swift中数组移除的方法名和用法和Objective-C中移除可变数组中的元素的方式极为相似。下方截图中是经常使用的移除方法,用法都没有什么难理解的地方,在此就简单的聊上一嘴。
Void removeAll(): 移除数组中全部元素,有一个可选参数,keepCapacity。如果keepCapacity = YES的话,那么数组移除元素后,其存储空间还是存在的,在此往里存储值,不需再给他分配存储空间了。如果keepCapacity=NO的话,那么数组的存储空间就会被回收掉。
String removeAtIndex(): 移除指定索引的元素,并且返回被移除的元素。
String removeFrist(): 移除第一个元素,并返回被移除的元素。
Void removeFirst(n: Int): 这个函数的意思是移除数组前方的几个元素,如果n = 1, 的话就移除前面一个元素这时与String removeFirst()函数功能相同。如果n = 3, 就移除前3个元素。
String removeLast(): 移除数组中最后一个元素。
Void removeRange(subRange: Range<Int>): 这个函数就比较全能呢,它可以移除数组中有效范围内的连续元素。它需要一个Range参数,下方是这个函数的使用方法,Range的起始位置是1,结束位置是2,就是移除索引1到2之间的元素。可以看Playground中的提示。 Range(start:1, end:2) 代表着半开区间1..<2。
3. 使用Array构造函数给数组赋初始值
在一些应用场景中我们需要为数组中的每一项进行初始化,也就是给数组的每一项赋上初始值。举个栗子~,比如我们要使用一个数组来记录公司每个季度的销售额,在数组初始化时,我们给给数组初始化4个初始值为零的元素。接下来就使用Array构造函数来做一些事情。下方就是在数组创建时给数组赋初始值。
二、Swift中的字典(Dictionary)
Swift中字典和Objective-C中的字典除了语法不一样外,用法也是大同小异的。字典中存放的就是Key和Value也就是键值对。可以通过Key来取出Value的值,在PHP这门强大的语言中,Array和Dictionary就是一个东西。其实数组就是一种特殊的字典,数组的key就是其下标,只不过这个下标不需要你去指定,由系统分配好,并且是元素在数组中是按下标从小到大排列的。在字典中的键值对是没有固定顺序的。
1. 字典的创建
在Swift中字典的创建和数组的创建也是类似的,就是比数组的item多了一个key。下方创建了两个字典,第一个字典是指定了key与value的数据类型,第二个字典没有为键值指定固定的数据类型。从Playground中我们容易的看出字典中的数据是没有固定数据的,因为读取字典中的值是通过key-value的形式而不是通过下标的方式。下方创建的都是可变字典,因为我们使用的是var关键字进行修饰的,如果你要创建不可变数组,我们就可以使用let关键字进行创建。关于let创建字典的内容,在此就不做过多的赘述了,因为只需要把下方的var换成let即可。
2. 字典item的增删改查
(1) 查询字典的值(读取)
我们可以通过字典键值对的key来取出key对应的value。 下方的代码是分别取出“大毛”和“小黄”的值,如下所示:
(2)字典的遍历
只取一个值那多不爽呢,下面介绍一下字典的遍历方法。下方是遍历输出字典myDog中所有的key,字典的keys属性是获取字典中所有的key值。
上述代码段输出结果如下,由输出结果可知,每个Value是可选类型的数据:
key: Optional("黄2")
key: Optional("小黄")
key: Optional("大黄")
上面是获取字典中的所有keys, 那么下面是获取字典中的所有values, 具体代码如下所示:
上述代码段输出的结果值如下:
接下来就是对字典的整个item进行遍历,每个item遍历出来是一个元组。元组的内容是(key, value)。遍历出来的元组我们就可以通过使用元组的形式来获取字典的key和value。具体代码如下所示:
输出结果如下:
(3) 字典的修改
字典元素的修改是比较简单的,下方通过两种。第一种是通过key的形式直接给key对应的value赋值,不过这种修改方式是不会返回被修改的值的,具体代码如下:
如果你想在修改值的时候返回被修改的原始值的话,你需要使用updateValue(forKey:)方法进行元素的修改。该函数是可以返回被修改的原始值的,具体实例如下所示:
(4) 增加元素
往已有的可变字典中增加元素就简单多了,直接通过key就可以给value赋值。在可变字典中,如果key已经存在,那么就变成上面的修改字典的值了。可以这么理解,通过key给value赋值时,如果key存在,就覆盖原有的键值对,如果不存在就添加。下方就是往字典中进行添加元素的语句:
(5)移除元素
下方截图中是所有字典移除元素的方法,
removeAll():移除所有元素。
removeAll(keepCapacity: Bool):移除所有元素, 如果keepCapacity为True,则保留字典原有的存储空间。
removeValueForkey(key: Hashable): 这个方法是通过key来移除元素的。
removeAtIndex(index: DictionaryIndex<Hashable, Value>):这个是通过Dictionary的索引来删除元素的。但是字典的item是没有顺序的,那么我们怎么获取这个DictionaryIndex呢? 那么我们就会使用到另一个函数,就是indexForKey。具体用法如下,移除元素成功后会以元组的形式返回被删除的值。