6.1 数组
数组用来存储一组有序的相同类型的变量。相同的值可以多次出现在数组的不同位置。
Swift 数组与 Objective-C 中的NSArray
以及NSMutableArray
不同,它只能存储相同类型的变量,所以它是类型安全的,并且永远确定所包含的是什么类型的变量。例如我们创建了一个由字符串类型的变量组成的数组,当我们试图插入一个整数类型时,我们在输入完这行代码时就会得到错误提示;如果我们从一个字符串类型的数组中获取某个值时,我们得到的永远是字符串类型。所以我们可以放心的进行字符串类型的操作,比如获取它的长度。在系统运行时,不会因为类型错误而导致程序崩溃。
数组类型的表示
- 第一种表示方法是
Array<SOMETYPE>
,其中SOMETYPE
是这个数组可以存储的变量类型。该数组所存储的所有变量都必须是该类型的。例如,我们用下面这个方法声明一个字符串类型的数组:
Array<String>()
注意
在类型后面加上()
表示我们实例化了一个该类型的数组
- 第二种是
SOMETYPE[]
。同样是字符串类型的数组,我们用下面这种写法:
String[]()
- 同样也可以
[String]()
数组字面值
可以通过字面值来初始化一个数组,数组字面值是由一组由逗号分割的数值及左右括起来的中括号组成:
[VALUE1, VALUE2, VALUE3]
下面的样例创建了一个名为shoppingList
的字符串数组:
var shoppingList: String[] = ["Eggs", "Milk"]
我们通过紧挨着变量名后面: String[]
显示的指明shoppingList
的类型是字符串数组, 因此这个数组所包含的值都是字符串类型,它只能存储字符串类型的元素。这里,shoppingList
被初始化为一个包含两个字符串元素的数组 ("Eggs"
和"Milk"
), 通过数组字面值声明。
注意
这里shoppingList
被声明为一个变量而不是常量,因为在后面例子中,我们将改变这个数组。
在 Swift 中,我们也可以不显示声明变量的类型:
var shoppingList = ["Eggs", "Milk"]
这与上面的代码等效。因为数组字面值中每个元素都是字符串,所以 Swift 推断shoppingList
的正确类型应该是String[]
。
访问/修改数组中的变量
可以通过数组类型的方法、属性或通过下标的方式访问数组的元素。
通过只读的属性count
获取数组的元素总数:
println("The shopping list contains \(shoppingList.count) items.")
通过布尔类型的isEmpty
属性判断数组是否为空:
if shoppingList.isEmpty {
println("The shopping list is empty")
} else {
println("The shopping list is not empty")
}
`isEmpty`与判断`count`等于零等价。
通过`append`方法在数组末尾添加一个元素:
```swift
shoppingList.append("Flour")
同样的,也可以通过操作符+=
在数组末尾添加元素:
shoppingList += "Baking Powder"
另外,通过+=
可以在数组末尾拼接一个另一个数组:
shoppingList += ["Chocolate Spread", "Cheese", "Butter"]
通过下标可以获取数组中的某个元素的值。将数字写在方括号中挨着写在数组变量后:
var firstItem = shoppingList[0]
注意,这里数组的第一个元素下标是0而不是1,Swift中的数组永远都是以下标0为开始的。
还可以通过下标修改数组中某个元素的值:
shoppingList[0] = "Six eggs"
可以通过下标的方式修改数组中一个子数组的值:
shoppingList[4...6] = ["Chocolate Spread", "Cheese", "Butter"]
// 修改 shoppingList[4] 为 Chocolate Spread, shoppingList[5] 为 Cheese, shoppingList[6] 为 Butter
即使赋值的数组和下标的子数组长度不同,也可以赋值
shoppingList[4...6] = ["Banana", "Apples"]
// 将 shoppingList 中的 ["Chocolate Spread", "Cheese", "Butter"] 替换为 ["Banana", "Apples"]
注意
下标不能超过数组的范围,不能通过下标在数组末尾添加元素。如果下标超过了数组的范围,程序运行时将会发生错误。在使用下标前可以判断数组的长度,下标的范围是 0 到count-1
的闭区间。如果count
为 0, 则不能通过下标获取或修改数组。
通过insert(atIndex:)
方法在数组的指定位置插入元素:
shoppingList.insert("Maple Syrup", atIndex:0)
// 在数组的最前面插入 Maple Syrup, 插入元素的位置在指定下标的前面
通过removeAtIndex
从指定位置删除元素:
let mapleSyrup = shoppingList.remoteAtIndex(0)
// 删除数组的第一个元素,其他元素下标全部减小 1
remoteAtIndex
方法会删除指定下标的元素,同时其他元素的下标减小 1。该方法会返回指定下标的元素,如果不需要可以忽略该返回值。
let firstItem = shoppingList[0]
// firstItem = "Six eggs"
此时数组的第一个元素又恢复为 Six eggs。
通过removeLast
方法删除数组的最后一个元素:
var lastItem = shoppingList.remoteLast();
这与shoppingList.remoteAtIndex(shoppingList.count - 1)
等价。
遍历数组
首先可以通过for-in
循环遍历一个数组
for item in shoppingList {
println(item)
}
该段代码将输出
Six eggs
Milk
Flour
Baking Powder
Bananas
如果需要元素的下标,则可以用enumerate
这个函数。该函数会为每个元素返回一个二元组,该二元组由数组元素的下标和元素的值组成。
for (index, value) in enumerate(shoppingList) {
printLn("Item \(index + 1) : \(value)")
}
这段代码将输出
Item 1: Six eggs
Item 2: Milk
Item 3: Flour
Item 4: Baking Powder
Item 5: Bananas
创建并初始化数组
创建空数组:
var someInts = Int[]()
即使我们没有通过someInts: Int[]
显示声明其类型,但是 Swift 还是可以推断出他的类型,因为我们给他赋值了一个空的整数数组:Int[]()
。
如果我们显式的声明了someInts
的类型,则可以不指明赋值的数组类型:
var someInts: [Int] = []
当someInts
声明后(声明后,其类型就确定了),就可以一直通过后面这种方式赋值了:
someInts = []
前面的例子中,我们都是使用()
来实例化一个数组变量,其实 Swift 提供了一些数组构造函数,可以往括号中传入参数,来帮助我们构建一个数组的实例。
例如:
var threeDoubles = Double[](count: 3, repeatedValue: 0.0)
// 该方法将构建一个浮点数组类型的实例 [0.0, 0.0, 0.0]
Swift 可以通过repeatedValue
推断出该数组的类型,所以不需要显示指名该类型:
var anotherThreeDoubles = Array(count: 3, repeatedValue: 2.5)
我们还可以通过将两个数组相加的方式,拼接两个数组并赋值给另一个数组:
var sixDoubles = threeDoubles + anotherThreeDoubles