Swift數組
數組
數組使用有序列表存儲同一類型的多個值。相同的值可以多次出現在一個數組的不同位置中。
Swift 數組特定於它所存儲元素的類型。這與 Objective-C 的 NSArray 和 NSMutableArray 不同,這兩個類可以存儲任意類型的對象,並且不提供所返回對象的任何特彆信息。在 Swift 中,數據值在被存儲進入某個數組之前類型必須明確,方法是通過顯式的類型標注或類型推斷,而且不是必須是class
類型。例如: 如果我們創建了一個Int
值類型的數組,我們不能往其中插入任何不是Int
類型的數據。 Swift 中的數組是類型安全的,並且它們中包含的類型必須明確。
數組的簡單語法
寫 Swift 數組應該遵循像Array<SomeType>
這樣的形式,其中SomeType
是這個數組中唯一允許存在的數據類型。 我們也可以使用像SomeType[]
這樣的簡單語法。 儘管兩種形式在功能上是一樣的,但是推薦較短的那種,而且在本文中都會使用這種形式來使用數組。
數組構造語句
我們可以使用字麵量來進行數組構造,這是一種用一個或者多個數值構造數組的簡單方法。字麵量是一係列由逗號分割並由方括號包含的數值。 [value 1, value 2, value 3]
。
下麵這個例子創建了一個叫做shoppingList
並且存儲字符串的數組:
var shoppingList: String[] = ["Eggs", "Milk"]
// shoppingList 已經被構造並且擁有兩個初始項。
shoppingList
變量被聲明為“字符串值類型的數組“,記作String[]
。 因為這個數組被規定隻有String
一種數據結構,所以隻有String
類型可以在其中被存取。 在這裡,shoppinglist
數組由兩個String
值("Eggs"
和"Milk"
)構造,並且由字麵量定義。
注意:
Shoppinglist
數組被聲明為變量(var
關鍵字創建)而不是常量(let
創建)是因為以後可能會有更多的數據項被插入其中。
在這個例子中,字麵量僅僅包含兩個String
值。匹配了該數組的變量聲明(隻能包含String
的數組),所以這個字麵量的分配過程就是允許用兩個初始項來構造shoppinglist
。
由於 Swift 的類型推斷機製,當我們用字麵量構造隻擁有相同類型值數組的時候,我們不必把數組的類型定義清楚。shoppinglist
的構造也可以這樣寫:
var shoppingList = ["Eggs", "Milk"]
因為所有字麵量中的值都是相同的類型,Swift 可以推斷出String[]
是shoppinglist
中變量的正確類型。
訪問和修改數組
我們可以通過數組的方法和屬性來訪問和修改數組,或者下標語法。 還可以使用數組的隻讀屬性count
來獲取數組中的數據項數量。
println("The shopping list contains \(shoppingList.count) items.")
// 輸出"The shopping list contains 2 items."(這個數組有2個項)
使用布爾項isEmpty
來作為檢查count
屬性的值是否為 0 的捷徑。
if shoppingList.isEmpty {
println("The shopping list is empty.")
} else {
println("The shopping list is not empty.")
}
// 打印 "The shopping list is not empty."(shoppinglist不是空的)
也可以使用append
方法在數組後麵添加新的數據項:
shoppingList.append("Flour")
// shoppingList 現在有3個數據項,有人在攤煎餅
除此之外,使用加法賦值運算符(+=
)也可以直接在數組後麵添加數據項:
shoppingList += "Baking Powder"
// shoppingList 現在有四項了
我們也可以使用加法賦值運算符(+=
)直接添加擁有相同類型數據的數組。
shoppingList += ["Chocolate Spread", "Cheese", "Butter"]
// shoppingList 現在有7項了
可以直接使用下標語法來獲取數組中的數據項,把我們需要的數據項的索引值放在直接放在數組名稱的方括號中:
var firstItem = shoppingList[0]
// 第一項是 "Eggs"
注意第一項在數組中的索引值是0
而不是1
。 Swift 中的數組索引總是從零開始。
我們也可以用下標來改變某個已有索引值對應的數據值:
shoppingList[0] = "Six eggs"
// 其中的第一項現在是 "Six eggs" 而不是 "Eggs"
還可以利用下標來一次改變一係列數據值,即使新數據和原有數據的數量是不一樣的。下麵的例子把"Chocolate Spread"
,"Cheese"
,和"Butter"
替換為"Bananas"
和 "Apples"
:
shoppingList[4...6] = ["Bananas", "Apples"]
// shoppingList 現在有六項
注意:
我們不能使用下標語法在數組尾部添加新項。如果我們試著用這種方法對索引越界的數據進行檢索或者設置新值的操作,我們會引發一個運行期錯誤。我們可以使用索引值和數組的count
屬性進行比較來在使用某個索引之前先檢驗是否有效。除了當count
等於 0 時(說明這是個空數組),最大索引值一直是count - 1
,因為數組都是零起索引。
調用數組的insert(atIndex:)
方法來在某個具體索引值之前添加數據項:
shoppingList.insert("Maple Syrup", atIndex: 0)
// shoppingList 現在有7項
// "Maple Syrup" 現在是這個列表中的第一項
這次insert
函數調用把值為"Maple Syrup"
的新數據項插入列表的最開始位置,並且使用0
作為索引值。
類似的我們可以使用removeAtIndex
方法來移除數組中的某一項。這個方法把數組在特定索引值中存儲的數據項移除並且返回這個被移除的數據項(我們不需要的時候就可以無視它):
let mapleSyrup = shoppingList.removeAtIndex(0)
// 索引值為0的數據項被移除
// shoppingList 現在隻有6項,而且不包括Maple Syrup
// mapleSyrup常量的值等於被移除數據項的值 "Maple Syrup"
數據項被移除後數組中的空出項會被自動填補,所以現在索引值為0
的數據項的值再次等於"Six eggs"
:
firstItem = shoppingList[0]
// firstItem 現在等於 "Six eggs"
如果我們隻想把數組中的最後一項移除,可以使用removeLast
方法而不是removeAtIndex
方法來避免我們需要獲取數組的count
屬性。就像後者一樣,前者也會返回被移除的數據項:
let apples = shoppingList.removeLast()
// 數組的最後一項被移除了
// shoppingList現在隻有5項,不包括cheese
// apples 常量的值現在等於"Apples" 字符串
數組的遍曆
我們可以使用for-in
循環來遍曆所有數組中的數據項:
for item in shoppingList {
println(item)
}
// Six eggs
// Milk
// Flour
// Baking Powder
// Bananas
如果我們同時需要每個數據項的值和索引值,可以使用全局enumerate
函數來進行數組遍曆。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
更多關於for-in
循環的介紹請參見for 循環。
創建並且構造一個數組
我們可以使用構造語法來創建一個由特定數據類型構成的空數組:
var someInts = Int[]()
println("someInts is of type Int[] with \(someInts.count) items。")
// 打印 "someInts is of type Int[] with 0 items。"(someInts是0數據項的Int[]數組)
注意someInts
被設置為一個Int[]
構造函數的輸出所以它的變量類型被定義為Int[]
。
除此之外,如果代碼上下文中提供了類型信息, 例如一個函數參數或者一個已經定義好類型的常量或者變量,我們可以使用空數組語句創建一個空數組,它的寫法很簡單:[]
(一對空方括號):
someInts.append(3)
// someInts 現在包含一個INT值
someInts = []
// someInts 現在是空數組,但是仍然是Int[]類型的。
Swift 中的Array
類型還提供一個可以創建特定大小並且所有數據都被默認的構造方法。我們可以把準備加入新數組的數據項數量(count
)和適當類型的初始值(repeatedValue
)傳入數組構造函數:
var threeDoubles = Double[](count: 3, repeatedValue:0.0)
// threeDoubles 是一種 Double[]數組, 等於 [0.0, 0.0, 0.0]
因為類型推斷的存在,我們使用這種構造方法的時候不需要特彆指定數組中存儲的數據類型,因為類型可以從默認值推斷出來:
var anotherThreeDoubles = Array(count: 3, repeatedValue: 2.5)
// anotherThreeDoubles is inferred as Double[], and equals [2.5, 2.5, 2.5]
最後,我們可以使用加法操作符(+
)來組合兩種已存在的相同類型數組。新數組的數據類型會被從兩個數組的數據類型中推斷出來:
var sixDoubles = threeDoubles + anotherThreeDoubles
// sixDoubles 被推斷為 Double[], 等於 [0.0, 0.0, 0.0, 2.5, 2.5, 2.5]