简介
Swift 语言提供
Arrays@H_502_7@、
Sets@H_502_7@和
Dictionaries@H_502_7@三种基本的集合类型用来存储集合数据。数组是有序数据的集;集合是无序无重复数据的集;字典是无序的键值对的集。
Swift 语言中的
Arrays@H_502_7@、
Sets@H_502_7@和
Dictionaries@H_502_7@中存储的数据值类型必须明确。
集合的可变性
- 使用
var@H_502_7@声明的
Arrays@H_502_7@、
Sets@H_502_7@、
Dictionaries@H_502_7@将是可变的,这意味着可以在创建之后添加更多或移除已存在的数据项来改变这个集合的大小;如果使用
let@H_502_7@来声明。,则意味着集合是不可变的,大小不能更改。
注意:如果不需要改变集合大小,请用
let@H_502_7@将集合声明成常量。
数组(Arrays)
- 数组是编程语言中最常见的一种数据结构,可用于存储多个数据,每个数组元素存放一个数据,通常可通过数组元素的索引来访问数组元素,包括为数组元素赋值和取出数组元素的值。
声明数组
Swift声明数组变量有两种语法:
注意:尽管两种语法在声明形式上基本一致,但是小编推荐使用简化语法声明数组。而且在本文中都会使用这种 形式来使用数组。
创建数组
使用Array@H_502_7@的构造器创建数组
- 使用构造语法
init()@H_502_7@来创建一个由特定数据类型构成的空数组:
var someInts: [Int] = Array()
print(someInts.count) // 输出 0
// 通过构造函数的类型,cards 的值类型被推断为 [String]
var cards = [String]()
- 使用构造语法
init(count:,repeatedValue:)@H_502_7@创建一个带有默认值的数组
var numbers: [Double] = Array(count: 3,repeatedValue: 0.0)
print(numbers) // 输出 [0.0,0.0,0.0]
使用简化语法创建数组
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]
使用数组
访问与修改数组元素
- 访问数组元素的格式为:
数组名[下标]@H_502_7@,Swift的数组索引是从0开始的,也就是说,第1个数组元素的索引值为0,最后一个数组元素的索引值为
数组长度-1@H_502_7@。访问到数组元素后,就可以把一个数组元素当成一个普通变量使用了,包括为该变量赋值(修改)和取出该变量的值,这个变量的类型就是定义数组时使用的类型。
var subjects = ["语文","地理"]
let subject = subjects[0]
print("主修课程:\(subject)") // 输出 主修课程:语文
subjects[0] = "物理"
print("主修课程:\(subjects[0])") // 输出 主修课程:物理
使用isEmpty@H_502_7@检查count@H_502_7@属性的值是否为0@H_502_7@
count@H_502_7@属性的值是否为0@H_502_7@
var colors = ["Red","White","Brown","Black"]
if colors.isEmpty {
print("数组 colors 为空。")
}else {
print("数组 colors 有\(colors.count)个元素,不为空。")
}
// 输出 数组 colors 有4个元素,不为空。
修改数组
添加元素
var cards = [String]()
cards.append("A")
cards.append("K")
cards.append("Q")
print(cards) // 输出 [A,K,Q]
print(cards.count) // 输出 3
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)@H_502_7@方法插入元素,需要说明的是,该方法的第二个参数不能超过数组长度(可以等于数组长度,当第二个参数等于数组长度时,调用
insert()@H_502_7@方法的效果与调用
append()@H_502_7@方法完全相同);否则,调用该方法将会导致数组索引越界的运行时错误。
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@H_502_7@,否则将会导致数组索引越界的运行时错误。
除此之外,
Array@H_502_7@还支持在方括号中(
[]@H_502_7@)使用
Range@H_502_7@,这样既可一次性地获取多个数组元素,也可一次性对多个数组元素进行赋值。
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)@H_502_7@:删除指定索引处的元素,该方法的参数不能大于数组的长度-1,否则将会导致数组索引越界。
removeAll(keepCapacity keepCapacity: Bool = default)@H_502_7@:清空数组。
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@H_502_7@循环遍历数组:
var letters = ["A","E"]
for letter in letters {
print(letter)
}
// 一次输出:A、B、C、D、E
- 如果我们同时需要每个数据项的值和索引值,可以使用
enumerate()@H_502_7@方法来进行数组遍历。
enumerate()@H_502_7@返回一个由每一个数据项索引值和数据值组成的元组。我们可以把这个元组分解成临时常量或者变量来进行遍历:
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@H_502_7@,另外一组值用于保存字典里的
value@H_502_7@,
key@H_502_7@和
value@H_502_7@都可以是任意类型的数据,字典的
key@H_502_7@不允许重复。
key@H_502_7@和
value@H_502_7@之间存在单向一对一的关系,即通过指定的
key@H_502_7@,可以找到对应的
value@H_502_7@。
字典和数组不同在于数组是有序的,字典是无序的。
声明字典
Swift的声明字典变量的有两种语法:
使用泛型语法:字典类型的语法格式为:
Dictionary<key 类型 :value 类型>@H_502_7@
使用简化语法:字典类型的语法格式为:
[key 类型 :value 类型]@H_502_7@
// 使用泛型语法声明字典
var dict1: Dictionary <String,String>
// 使用简化语法声明字典
var dict2: [String : Int]
创建字典
使用Dictionary的构造器创建字典
- 使用构造语法创建一个拥有确定类型的空字典:
// 创建 [String : Double] 类型的空数组,它的键是 String 型,值是 Double 型。
var scores = [String : Double]()
使用简化语法创建字典
var studentInfo = ["姓名":"小张","年龄":"19岁","地址":"四川成都"]
print(studentInfo) // 输出 [年龄: 19岁,地址: 四川成都,姓名: 小张]
- Swift允许使用
[:]@H_502_7@创建空字典。
var emptyDict: [String : Double] = [ : ]
print(emptyDict) // 输出 [ : ]
使用字典
读取和修改字典
- 字典最常用的用法就是根据
key@H_502_7@访问字典中对应的
value@H_502_7@,包括对
value@H_502_7@进行赋值和取出
value@H_502_7@的值。访问字典的
value@H_502_7@只需再字典变量后紧跟一个方括号(
[]@H_502_7@),方括号里是字典
value@H_502_7@对应的
key@H_502_7@。访问到字典的
value@H_502_7@后,就可以把
value@H_502_7@当成一个普通变量使用了,包括为该变量赋值和取出该变量的值,这个变量的类型就是定义字典时为
value@H_502_7@所指定的类型。
// 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@H_502_7@访问字典对应的
value@H_502_7@时,字典并非直接返回字典的
value@H_502_7@的类型,而是返回包含
value@H_502_7@的可选类型,这是因为字典并不确定程序视图访问的
key-value@H_502_7@对是否存在,当该
key-value@H_502_7@对存在时,字典返回该
key@H_502_7@对应的
value@H_502_7@;当
key-value@H_502_7@对不存在时,字典返回
nil@H_502_7@。
由于字典根据
key@H_502_7@访问
value@H_502_7@返回的是包含
value@H_502_7@的可选类型,因此字典需要对返回的
value@H_502_7@使用感叹号进行强制解析。
var infoDict = ["name" : "Edward"]
print(infoDict["name"]!) // 输出 Edward
- 当程序通过
key@H_502_7@设置字典的
value@H_502_7@时,如果对应的
key-value@H_502_7@对存在时,程序将会修改该
key@H_502_7@对应的
value@H_502_7@;如果对应的
key-value@H_502_7@对不存在时,程序将会为字典添加
key-value@H_502_7@对。上述代码示例中通过这种方式为
infoDcit@H_502_7@添加了3组
key-value@H_502_7@对。
使用updateValue()@H_502_7@添加或修改字典
- 与使用
字典[key]@H_502_7@形式对
value@H_502_7@赋值类似的是,字典还提供了
updateValue(value: Value,forKey key: Key) -> Value?@H_502_7@方法,该方法同样可以修改已有
key@H_502_7@对应的
value@H_502_7@,或
key-value@H_502_7@对,但
updateValue()@H_502_7@方法更加强大,该方法可以返回被修改的
value@H_502_7@之前的原值,这样方便程序检测是否修改成功。
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@H_502_7@检查字典是否为空
var emptyDict: [String : Double] = [ : ]
print(emptyDict.isEmpty) // 输出 true
字典遍历
var studentInfo = ["姓名":"小张","地址":"四川成都"]
for (key,value) in studentInfo {
print("\(key):\(value)")
}
// 年龄:19岁
// 地址:四川成都
// 姓名:小张
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 '姓名'.
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@H_502_7@声明字典是可变字典。