数组是 Swift 三种主要集合类型之一。 数组是有序的元素列表。 数组可以存储任意类型的元素,但同一个数组中的所有元素必须类型相同。 把数组赋值给变量时,它是可变的,也就是说创建数组之后,你可以添加、删除或修改其中的元素。 赋值给常量时,数组是不可变的,也就是说它的内容无法更改。
数组字面量写成用方括号([...])括起来、以逗号分隔的元素列表。
Swift 可以从字面量中的元素推断出数组的类型。
let evenInts = [2, 4, 6, 8, 10, 12]
var oddInts = [1, 3, 5, 7, 9, 11, 13]
let greetings = ["Hello!", "Hi!", "¡Hola!"]
你也可以显式指定类型。
数组类型有两种写法:Array<T> 或简写形式 [T],其中 T 是数组所含值的类型。
let evenInts: Array<Int> = [2, 4, 6, 8, 10, 12]
var oddInts: [Int] = [1, 3, 5, 7, 9, 11, 13]
let greetings: [String] = ["Hello!", "Hi!", "¡Hola!"]
你可以使用数组的 count 属性获取其中元素的数量:
evenInts.count
// returns 6
要创建空数组,必须指定它的类型。 你可以使用数组初始化语法或显式的类型标注:
let emptyArray = [Int]()
let emptyArray2 = Array<Int>()
let emptyArray3: [Int] = []
数组可以嵌套,从而创建多维数组。
显式指定嵌套数组的类型时,要把元素类型包在嵌套的方括号中,例如 [[Int]] 或 Array<Array<Int>>:
let multiDimArray = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let multiDimArray2: [[Int]] = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
你可以使用 append(_:) 方法把元素添加到可变数组的末尾:
var oddInts = [1, 3, 5, 7, 9, 11, 13]
oddInts.append(15)
// oddInts is now [1, 3, 5, 7, 9, 11, 13, 15]
你可以使用 insert(_:at:) 方法在指定的下标处插入元素。
这个方法接收两个实参:要插入的元素,以及插入位置的下标。
var oddInts = [1, 3, 5, 7, 9, 11, 13]
oddInts.insert(0, at: 0)
// oddInts is now [0, 1, 3, 5, 7, 9, 11, 13]
你可以使用 + 运算符把两个数组合并成一个数组。
+ 运算符会创建并返回一个新数组,它不会修改原来的数组。
var oddInts = [1, 3, 5, 7, 9, 11, 13]
let combined = oddInts + [15, 17, 19]
// combined is [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
print(oddInts)
// prints [1, 3, 5, 7, 9, 11, 13]
把下标放在数组名后面的方括号([])中,就可以访问数组中的单个元素。
数组下标是从零开始的 Int 值,第一个元素的下标为 0。
访问超出有效范围的下标会导致运行时错误,使程序崩溃。
let evenInts = [2, 4, 6, 8, 10, 12]
let oddInts = [1, 3, 5, 7, 9, 11, 13]
evenInts[2]
// returns 6
oddInts[7]
// Fatal error: Index out of range
你可以给某个下标赋新值,从而修改可变数组中的元素。 与读取元素一样,使用超出有效范围的下标会导致运行时错误。
var evenInts = [2, 4, 6, 8, 10, 12]
evenInts[2] = 0
// evenInts is now [2, 4, 0, 8, 10, 12]
你可以使用 joined(separator:) 方法把一个字符串数组连接成单个字符串,它接收一个分隔字符串:
let evenInts = ["2", "4", "6", "8", "10", "12"]
let evenIntsString = evenInts.joined(separator: ", ")
// returns "2, 4, 6, 8, 10, 12"
你可以使用 split(separator:) 方法把字符串拆分成子字符串组成的数组,并传入分隔字符:
let evenIntsString = "2, 4, 6, 8, 10, 12"
let evenInts = evenIntsString.split(separator: ",")
// returns ["2", " 4", " 6", " 8", " 10", " 12"]
你可以使用 remove(at:) 方法删除指定下标处的元素。
下标必须在数组的有效范围内,否则会发生运行时错误。
var oddInts = [1, 3, 5, 7, 9, 11, 13]
oddInts.remove(at: 3)
// oddInts is now [1, 3, 5, 9, 11, 13]
要删除数组的最后一个元素,请使用 removeLast() 方法。
对空数组调用 removeLast() 会导致运行时错误。
var oddInts = [1, 3, 5, 7, 9, 11, 13]
oddInts.removeLast()
// oddInts is now [1, 3, 5, 7, 9, 11]
作为一名准魔术师,Elyse 需要练习一些基本功。 她有一摞牌想要摆弄一下。
为了让事情简单一点,她只用 1 到 10 这些牌,这样她的牌堆就可以用一个数字数组来表示。 某张牌的位置对应它在数组中的下标。 也就是说,位置 0 指第一张牌,位置 1 指第二张牌,以此类推。
所有函数都应该先更新这个牌堆数组,再返回修改后的数组。这是一种常见的做法,叫做 Builder 模式,它可以让你把多个函数漂亮地串联起来。
要取出一张牌,就返回给定牌堆中下标为position的那张牌。
实现函数getCard(at:from:),它接收两个参数:at表示牌在牌堆中的位置,from表示牌堆。
这个函数应该返回给定牌堆中下标为index的那张牌。
let index = 2
getCard(at: index, from: [1, 2, 4, 1])
// returns 4
耍个戏法,把下标为position的那张牌换成提供的替换牌。
实现函数setCard(at:in:to),它接收三个参数:at表示牌在牌堆中的位置,in表示牌堆,to表示用来替换下标为index那张牌的新牌。
这个函数应该返回牌堆的一个副本,其中下标为index的那张牌被替换成新牌。
如果给定的index不是牌堆中的有效下标,就应该原样返回原来的牌堆,不做修改。
let index = 2
let newCard = 6
setCard(at: index, in: [1, 2, 4, 1], to: newCard)
// returns [1, 2, 6, 1]
通过在牌堆顶部插入一张新牌,让一张牌出现。
实现函数insert(_:atTopOf:),它接收两个参数:要插入的新牌,以及牌堆。
这个函数应该返回牌堆的一个副本,把提供的新牌加到牌堆顶部。
let newCard = 8
insert(newCard, atTopOf: [5, 9, 7, 1])
// returns [5, 9, 7, 1, 8]
通过从牌堆中移除给定position位置的那张牌,让一张牌消失。
实现函数removeCard(at:from:),它接收两个参数:at表示牌在牌堆中的位置,from表示牌堆。
这个函数应该返回牌堆的一个副本,其中下标为index的那张牌被移除。
如果给定的index不是牌堆中的有效下标,就应该原样返回原来的牌堆,不做修改。
let index = 2
removeCard(at: index, from: [3, 2, 6, 4, 8])
// returns [3, 2, 4, 8]
通过在牌堆中给定的position位置插入一张新牌,让一张牌出现。
实现函数insert(_:at:from:),它接收三个参数:要插入的新牌、新牌应该插入的位置,以及牌堆。
这个函数应该返回牌堆的一个副本,把提供的新牌加到给定位置。
如果给定的index不是牌堆中的有效下标,就应该原样返回原来的牌堆,不做修改。
let newCard = 8
insert(newCard, at: 2, from: [5, 9, 7, 1])
// returns [5, 9, 8, 7, 1]
检查牌堆的大小是否等于stackSize。
实现函数checkSizeOfStack(_:_:),它接收两个参数:stack表示牌堆,stackSize表示牌堆的大小。
如果牌堆的大小等于stackSize,函数应该返回true,否则返回false。
let stackSize = 4
checkSizeOfStack([3, 2, 6, 4, 8], stackSize)
// returns false