简介
Swift 语言提供
Arrays
、Sets
和Dictionaries
三种基本的集合类型用来存储集合数据。数组是有序数据的集;集合是无序无重复数据的集;字典是无序的键值对的集。Swift 语言中的
Arrays
、Sets
和Dictionaries
中存储的数据值类型必须明确。
集合的可变性
- 使用
var
声明的Arrays
、Sets
、Dictionaries
将是可变的,这意味着可以在创建之后添加更多或移除已存在的数据项来改变这个集合的大小;如果使用let
来声明。,则意味着集合是不可变的,大小不能更改。
注意:如果不需要改变集合大小,请用
let
将集合声明成常量。
数组(Arrays)
- 数组是编程语言中最常见的一种数据结构,可用于存储多个数据,每个数组元素存放一个数据,通常可通过数组元素的索引来访问数组元素,包括为数组元素赋值和取出数组元素的值。
声明数组
Swift声明数组变量有两种语法:
使用泛型语法。数组类型的语法格式为:
Array<类型>
使用简化语法。数组类型的语法格式为:
[类型]
注意:尽管两种语法在声明形式上基本一致,但是小编推荐使用简化语法声明数组。而且在本文中都会使用这种 形式来使用数组。
创建数组
使用Array
的构造器创建数组
- 使用构造语法
init()
来创建一个由特定数据类型构成的空数组:
var someInts: [Int] = Array()
print(someInts.count) // 输出 0
// 通过构造函数的类型,cards 的值类型被推断为 [String]
var cards = [String]()
- 使用构造语法
init(count:,repeatedValue:)
创建一个带有默认值的数组
var numbers: [Double] = Array(count: 3,repeatedValue: 0.0)
print(numbers) // 输出 [0.0,0.0,0.0]
使用简化语法创建数组
- 数组的简化语法直接使用方括号(
[]
)列出多个数组值即可。创建数组的简化语法如:[value1,value2,value3,...]
var values: [Int] = [1,2,3,4,5]
var subjects = ["语文","数学","外语","政治","历史","地理"] // 系统推断类型为[String]
使用两个数组相加创建一个新的数组
var classA = [1,3]
var classB = [4,5,6]
var classC = classA + classB
print(classC) // 输出 [1,2,3,4,5,6]
使用数组
访问与修改数组元素
- 访问数组元素的格式为:
数组名[下标]
,Swift的数组索引是从0开始的,也就是说,第1个数组元素的索引值为0,最后一个数组元素的索引值为数组长度-1
。访问到数组元素后,就可以把一个数组元素当成一个普通变量使用了,包括为该变量赋值(修改)和取出该变量的值,这个变量的类型就是定义数组时使用的类型。
var subjects = ["语文","地理"]
let subject = subjects[0]
print("主修课程:\(subject)") // 输出 主修课程:语文
subjects[0] = "物理"
print("主修课程:\(subjects[0])") // 输出 主修课程:物理
使用isEmpty
检查count
属性的值是否为0
var colors = ["Red","White","Brown","Black"]
if colors.isEmpty {
print("数组 colors 为空。")
}else {
print("数组 colors 有\(colors.count)个元素,不为空。")
}
// 输出 数组 colors 有4个元素,不为空。
修改数组
- 使用
var
声明的数组变量允许被修改。
添加元素
var cards = [String]()
cards.append("A")
cards.append("K")
cards.append("Q")
print(cards) // 输出 [A,K,Q]
print(cards.count) // 输出 3
- 除此之外,Swift允许使用加法赋值运算符(
+=
)在数组后面添加一个或多个拥有相同类型的数据项。
cards += ["J"]
print(cards) // 输出 [A,Q,J]
print(cards.count) // 输出 4
cards += ["10","9","8"]
print(cards) // 输出 [A,J,10,9,8]
print(cards.count) // 输出 7
插入元素
- Swift提供了
insert(newElement: Element,atIndex i: Int)
方法插入元素,需要说明的是,该方法的第二个参数不能超过数组长度(可以等于数组长度,当第二个参数等于数组长度时,调用insert()
方法的效果与调用append()
方法完全相同);否则,调用该方法将会导致数组索引越界的运行时错误。
var languages = ["Swift"]
// 插入一个元素
languages.insert("Objective-C",atIndex: 0)
// 插入一个元素,指定 atIndex: 2,标明该元素插入数组的最后
languages.insert("Java",atIndex: 2)
print(languages)
print(languages.count)
// 下面代码指定 atIndex 超过了数组长度,因此将会导致错误
languages.insert("C++",atIndex: 4)
数组和范围
前面已经介绍了使用下标语法来访问数组元素和对数组元素赋值,唯一需要注意的是:使用下标来访问数组元素或对数组元素赋值时,程序所使用的下标
不能大于数组的长度-1
,否则将会导致数组索引越界的运行时错误。除此之外,
Array
还支持在方括号中([]
)使用Range
,这样既可一次性地获取多个数组元素,也可一次性对多个数组元素进行赋值。
var students = ["小七","小黄","小李","小张","小黑"]
// 获取 students 数组中索引为 1~3 的元素
let subRange = students[1..<4]
print(subRange) // 输出 [小黄,小李,小张]
// 将 students 数组中索引为 2~3 的元素替换成 "小白","小雪"
students[2...3] = ["小白","小雪"]
print(students) // 输出 [小七,小黄,小白,小雪,小黑]
// 将 students 数组织中索引为 0~1 的元素替换成 "A","B","C"
students[0...1] = ["A","B","C"]
print(students) // 输出 [A,B,C,小黑]
- 当程序对指定范围的数组元素赋值时,并不需要指定范围包括的元素个数与所赋值的元素个数相同,如果所赋值的元素少于范围内包含的元素个数,程序将会自动减少Swift数组的长度;如果所赋值的元素多于范围内包含的元素个数,程序将会自动增加Swift的长度。因此,程序可以通过这种方式添加或删除元素,例子如下:
// 清空数组
students[0..<students.count] = []
print(students) // 输出 []
删除元素
removeAtIndex(index: Int)
:删除指定索引处的元素,该方法的参数不能大于数组的长度-1,否则将会导致数组索引越界。removeLast()
:删除数组的最后一个元素。removeAll(keepCapacity keepCapacity: Bool = default)
:清空数组。
var letters = ["A","C","D","E"]
letters.removeAtIndex(2)
print(letters) // 输出 [A,D,E]
letters.removeLast()
print(letters) // 输出 [A,D]
letters.removeAll()
print(letters) // 输出 []
数组遍历
for-in
循环遍历数组:
var letters = ["A","E"]
for letter in letters {
print(letter)
}
// 一次输出:A、B、C、D、E
- 如果我们同时需要每个数据项的值和索引值,可以使用
enumerate()
方法来进行数组遍历。enumerate()
返回一个由每一个数据项索引值和数据值组成的元组。我们可以把这个元组分解成临时常量或者变量来进行遍历:
var letters = ["A","E"]
for (index,value) in letters.enumerate() {
print("Item \(String(index + 1)) is '\(value)'. ")
}
// Item 1 is 'A'.
// Item 2 is 'B'.
// Item 3 is 'C'.
// Item 4 is 'D'.
// Item 5 is 'E'.
字典(Dictionaries)
字典用于保存具有映射关系的数据,因此字典集合里保存着两组值,其中一组值用于保存字典里的
key
,另外一组值用于保存字典里的value
,key
和value
都可以是任意类型的数据,字典的key
不允许重复。key
和value
之间存在单向一对一的关系,即通过指定的key
,可以找到对应的value
。字典和数组不同在于数组是有序的,字典是无序的。
声明字典
Swift的声明字典变量的有两种语法:
使用泛型语法:字典类型的语法格式为:
Dictionary<key 类型 :value 类型>
使用简化语法:字典类型的语法格式为:
[key 类型 :value 类型]
// 使用泛型语法声明字典
var dict1: Dictionary <String,String>
// 使用简化语法声明字典
var dict2: [String : Int]
创建字典
使用Dictionary的构造器创建字典
- 使用构造语法创建一个拥有确定类型的空字典:
// 创建 [String : Double] 类型的空数组,它的键是 String 型,值是 Double 型。
var scores = [String : Double]()
使用简化语法创建字典
- 字典的简化语法直接使用方括号列出
key-value
对即可,其格式为:[key1:value1,key2:value2,key3:value3,...]
var studentInfo = ["姓名":"小张","年龄":"19岁","地址":"四川成都"]
print(studentInfo) // 输出 [年龄: 19岁,地址: 四川成都,姓名: 小张]
- Swift允许使用
[:]
创建空字典。
var emptyDict: [String : Double] = [ : ]
print(emptyDict) // 输出 [ : ]
使用字典
读取和修改字典
- 字典最常用的用法就是根据
key
访问字典中对应的value
,包括对value
进行赋值和取出value
的值。访问字典的value
只需再字典变量后紧跟一个方括号([]
),方括号里是字典value
对应的key
。访问到字典的value
后,就可以把value
当成一个普通变量使用了,包括为该变量赋值和取出该变量的值,这个变量的类型就是定义字典时为value
所指定的类型。
// 1、初始化字典
var infoDict = ["name" : "Edward"]
// 2、访问指定key对应的value
print(infoDict["name"]) // 输出 Optional("Edward")
// 3、访问并不存在的key对应的value时,将会返回nil。
print(infoDict["noExisy"]) // 输出 nil
// 4、修改指定key对应的value
infoDict["name"] = "Charles"
print(infoDict["name"]) // 输出 Optional("Charles")
// 5、对不存在key设置value,该字典将会添加key-value对
infoDict["age"] = "22"
infoDict["address"] = "ChengDu"
infoDict["phone"] = "13219038892"
print(infoDict) // 输出 [age: 22,address: ChengDu,phone: 13219038892,name: Charles]
上述例子中,当程序根据
key
访问字典对应的value
时,字典并非直接返回字典的value
的类型,而是返回包含value
的可选类型,这是因为字典并不确定程序视图访问的key-value
对是否存在,当该key-value
对存在时,字典返回该key
对应的value
;当key-value
对不存在时,字典返回nil
。由于字典根据
key
访问value
返回的是包含value
的可选类型,因此字典需要对返回的value
使用感叹号进行强制解析。
var infoDict = ["name" : "Edward"]
print(infoDict["name"]!) // 输出 Edward
- 当程序通过
key
设置字典的value
时,如果对应的key-value
对存在时,程序将会修改该key
对应的value
;如果对应的key-value
对不存在时,程序将会为字典添加key-value
对。上述代码示例中通过这种方式为infoDcit
添加了3组key-value
对。
使用updateValue()
添加或修改字典
- 与使用
字典[key]
形式对value
赋值类似的是,字典还提供了updateValue(value: Value,forKey key: Key) -> Value?
方法,该方法同样可以修改已有key
对应的value
,或key-value
对,但updateValue()
方法更加强大,该方法可以返回被修改的value
之前的原值,这样方便程序检测是否修改成功。
var login = ["account" : "admin","password" : "123456"]
let result1 = login.updateValue("654321",forKey: "password")
print(result1) // 输出 Optional("123456")
let result2 = login.updateValue("123456789@qq.com",forKey: "email")
print(result2) // 输出 nil
print(login) // 输出 [email: 123456789@qq.com,account: admin,password: 654321]
使用isEmpty
检查字典是否为空
var emptyDict: [String : Double] = [ : ]
print(emptyDict.isEmpty) // 输出 true
字典遍历
- Swift允许使用
for-in
循环遍历字典。每一个字典中的数据项都以(key,value)
元组形式返回,并且我们可以使用临时常量或者变量来分解这些元组:
var studentInfo = ["姓名":"小张","地址":"四川成都"]
for (key,value) in studentInfo {
print("\(key):\(value)")
}
// 年龄:19岁
// 地址:四川成都
// 姓名:小张
- 通过访问
keys
或者values
属性,也可以遍历字典的键或者值。
var studentInfo = ["姓名":"小张","地址":"四川成都"]
for value in studentInfo.values {
print("the value is '\(value)'.")
}
// the value is '19岁'.
// the value is '四川成都'.
// the value is '小张'.
for key in studentInfo.keys {
print("the key is '\(key)'.")
}
// the key is '年龄'.
// the key is '地址'.
// the key is '姓名'.
- Swift允许通过字典的
keys
属性以及values
初始化一个新的数组。
let keys = Array(studentInfo.keys)
let values = Array(studentInfo.values)
let tests = ["A" : "1","B" : "2","C" : "3"]
let keys = Array(tests.keys)
print(keys.sort()) // 输出 [A,D]
字典的可变性和字典的修改
- 用
var
声明字典是可变字典。
添加、修改key-value
对
通过
字典[索引]
形式操作对应的key-value
对;通过
updateValue()
方法操作对应的key-value
对;
删除key-value
对
通过
removeAll(keepCapacity keepCapacity: Bool = default)
方法移除所有key-value
对。通过
removeValueForKey(key: Key) -> Value?
移除指定key-value
对。