集合类型
Swift提供三种集合类型, 分别为arrays
, sets
, and dictionaries
, 他们都是存储型数据类型, Arrays
存储有序数据的集合, Sets
存储无序的但有唯一数值的集合, Dictionaries
是无序的key-value
(键值对)的组合
我们在存储数据的时候应该非常清楚Arrays
sets
dictionaries
他们可以存储什么类型的数据, 这意味着你无法讲一个错误数据类型的数据插入到集合中, 也就是你准确的从集合中取出相应类型的数据
Note:
Swift的array, set, and dictionary是通用的集合类型, 了解泛型集合,请看
1: 集合的可变性
如果你创建一个array
, dictionary
, set
并且赋值给一个变量, 这个组合就是一个可变的。你可以增删改这个集合, 如果你创建一个array
, dictionary
, set
并且赋值给一个常量, 这个集合的大小内容都不可以修改.
Note:
确认一个集合是不需要修改的, 此时创建一个不可变的集合是非常棒的, 这样做有利于你理解代码并有利于Swift编译器优化你的集合性能
2: Arrays
数组是存储相同类型的有序列表。相同的值可以在不同位置多次出现在数组中。
Note:
Swift的Array可以桥接到Foundation框架的NSArray类, 想要了解更多Foundation and Cocoa下Array的使用, 请看Using Swift with Cocoa and Objective-C (Swift 4)的Working with Cocoa Data Types篇
2.1: 数组类型的速记语法
Swift数组的类型全部想 Array<Element>
, 当Element
的类型是数组接受的才可以保存, 你也可以简写[Element], 虽然这两种形式在功能上是相同的,但是简写形式更值得推崇,并且本指南中使用引用数组都是使用简写形式
2.2: 创建一个空的数组
初始化定义一个空数组
var someInts = [Int]()
print("someInts is of type [Int] with \(someInts.count) items.")
// Prints "someInts is of type [Int] with 0 items."
请注意,someInts
变量的类型在初始化的时候推断为[Int]。
如果上下文已经提供了类型信息,例如函数参数或已经键入的变量或常量,则可以创建一个空数组,其中有一个空数组文字,写为[]
(一对空方括号):
someInts.append(3)
// someInts now contains 1 value of type Int
someInts = []
// someInts is now an empty array, but is still of type [Int]
2.3: 创建具有默认值的数组
Swift的数组提供了创建特定大小特定数值的初始化方法, 您将该初始化方法传递为适当类型(称为repeat)的默认值:和新数组默认值的数量(称为count):
var threeDoubles = Array(repeating: 0.0, count: 3)
// threeDoubles is of type [Double], and equals [0.0, 0.0, 0.0]
2.4: 两个数组拼接初始化一个数组
您可以通过使用加法运算符(+)将两个具有兼容类型的现有数组相加在一起来创建一个新数组。新数组的类型根据您添加两个数组的类型推断:
var anotherThreeDoubles = Array(repeating: 2.5, count: 3)
// anotherThreeDoubles is of type [Double], and equals [2.5, 2.5, 2.5]
var sixDoubles = threeDoubles + anotherThreeDoubles
// sixDoubles is inferred as [Double], and equals [0.0, 0.0, 0.0, 2.5, 2.5, 2.5]
2.5: 数组文字初始化数组
您还可以使用数组文字初始化数组,这是将一个或多个值作为数组集合写入的简写方式。数组文字被写成一个值列表,用逗号分隔,用一对方括号包围:
[value 1, value 2, value 3]
下面的示例创建一个名为shoppingList
的数组来存储String
值:
var shoppingList: [String] = ["Eggs", "Milk"]
// shoppingList has been initialized with two initial items
shoppingList
变量被声明为“字符串值的数组”,写成[String]
。 因为这个特定的数组指定了一个值类型的String
,所以只允许存储String值。 在这里,使用两个字符串值(“Eggs”和“Milk”)初始化shoppingList
数组,写入数组文字。
Note
这个shoppingList
数组被定义为一个变量而不是常量, 因为在下面的示例中还要添加更多的元素
在这种情况下,数组字面值包含两个String
值,没有其他值。 这匹配了shoppingList
变量的声明类型(一个只能包含String
值的数组),因此允许使用数组文字的赋值作为初始化shoppingList
的两个初始项。
因为有Swift的类型自动推断,如果您使用包含相同类型值的数组文字来初始化数组,则不必编写该数组的类型。 shoppingList
的初始化可以以简约的格式写成:
var shoppingList = ["Eggs", "Milk"]
因为数组文字中的所有值都是相同的类型,所以Swift可以推到出[String]
并用于shoppingList
变量的正确类型。
2.6: 操作和修改数组
你可以操作和修改数组通过方法、属性甚至下标
查找数组的数量, 可以用只读属性的count
print("The shopping list contains \(shoppingList.count) items.")
// Prints "The shopping list contains 2 items."
使用布尔的isEmpty
属性作为检查count
属性是否等于0的简便方法:
if shoppingList.isEmpty {
print("The shopping list is empty.")
} else {
print("The shopping list is not empty.")
}
// Prints "The shopping list is not empty."
你可以通过使用数组的append(_:)
方法在数组的尾部增加一个元素
shoppingList.append("Flour")
// shoppingList now contains 3 items, and someone is making pancakes
或者,使用加法赋值运算符(+=
)附加一个或多个兼容项目的元素:
shoppingList += ["Baking Powder"]
// shoppingList now contains 4 items
shoppingList += ["Chocolate Spread", "Cheese", "Butter"]
// shoppingList now contains 7 items
通过使用下标语法从数组中检索一个值,在数组名称之后立即传递要在方括号内检索的值的索引:
var firstItem = shoppingList[0]
// firstItem is equal to "Eggs"
数组中的第一个项目的索引为0,而不是1. Swift中的数组始终为零开始
您可以使用下标语法来更改给定索引处的数值:
shoppingList[0] = "Six eggs"
// the first item in the list is now equal to "Six eggs" rather than "Eggs"
当您使用下标语法时,您指定的索引必须是有效的。例如,写入shoppingList [shoppingList.count] =“Salt
以尝试将一个项目附加到数组的末尾导致运行时错误。
您也可以使用下标语法来一次性更改值范围,即使替换值的值与要替换的范围的长度不同。 以下示例用“香蕉”和“苹果”替代“巧克力蔓延”,“奶酪”和“黄油”:
shoppingList[4...6] = ["Bananas", "Apples"]
// shoppingList now contains 6 items
要将一个元素插入到指定索引的数组中,请调用数组的insert(_:at :)
方法:
shoppingList.insert("Maple Syrup", at: 0)
// shoppingList now contains 7 items
// "Maple Syrup" is now the first item in the list
对insert(_:at:)
方法的调用将在购物清单开始处插入一个值为“Maple Syrup”的新项,由索引为0表示。
同样,您可以使用remove(at :)方法从数组中删除一个项目。此方法将删除指定索引处的项目并返回已删除的项目(尽管如果不需要则可以忽略返回的值):
let mapleSyrup = shoppingList.remove(at: 0)
// the item that was at index 0 has just been removed
// shoppingList now contains 6 items, and no Maple Syrup
// the mapleSyrup constant is now equal to the removed "Maple Syrup" string
Note:
如果您尝试访问或修改不在数组现有边界之外的索引的值,则会触发运行时错误。 您可以通过将索引与数组的count属性进行比较来检查索引是否有效。 数组中最大的有效索引是count-1,因为数组从零开始索引 - 但是,当count为0(表示数组为空)时,没有有效的索引。
删除项目时,数组中的任何间隙都会关闭,因此索引号0的值再次等于“Six eggs”:
firstItem = shoppingList[0]
// firstItem is now equal to "Six eggs"
如果要从数组中删除最终的项目,请使用removeLast()
方法而不是remove(at:)
方法来避免查询数组的count
属性。像remove(at:)
方法一样,removeLast()
返回删除的项:
let apples = shoppingList.removeLast()
// the last item in the array has just been removed
// shoppingList now contains 5 items, and no apples
// the apples constant is now equal to the removed "Apples" string