swift集合类型_swift数组_swift字典

分享到:

集合类型

Swift提供两个集合类型,即数组和字典,用于存储值集合。数组储存在相同类型的数值有序表内。字典存储相同类型值的无序集合,可以通过一个唯一标识符(也称为密钥)进行访问和查阅。

Swift中的数组和字典明确表明可以存储的值和密钥的类型。这意味着你不能在数组或字典中插入任何一个的错误类型的数值。这也表明你可以确信数组或字典中数值类型的检索。Swift的使用显式类型集合,确保代码可以清楚地表达它所服务的数值类型,可以帮助你在代码编写的初期获取任何不匹配类型。

注:当Swift的数组类型被指定给一个常量或变量,或当传递给一个函数或方法时,其会表现出不同的形式。更多信息可参考集合可变性和集合类型的配置和拷贝行为。

数组

一个数组可以在一个有序列表中存储同一类型的多值数值。相同数值可以在一个数组的不同位置多次出现。

Swift 数组特别指代它可以存储几类数值。Swift数组不同于Objective-C的NSArray和NSMutableArray,后者都可以存储任何类型的对象,但不能提供的处理后的任何信息。在Swift中,特别是数组中,无论是通过显式类型注释或通过类型推断,数值的存储都非常明确,不局限于一个类类型。例如,当你创建一个Int值的数组时,你不能插入除了Int值之外的其他任何值到数组中。Swift数组迅速、安全而且内容清晰。

数组类型句法

数组缩写语法

Swift数组类型的编写形式是Array<SomeType>,这是一个允许存储的字节。你也可以用缩写形式SomeType []来进行数组编写。虽然这两种形式的作用相同,但是在数组编写指南中提到数组类型时主要使用缩写形式。

数组常值

你可以用数组常值初始化一个数组,这是在编写数组集合时的一个缩写形式。数组常值可以作为列表数值编写,写在括号中。以逗号分隔: [value 1 , value 2 , value 3 ] 下面的示例是一个存储String数值创建的shoppingList数组:

 
var shoppingList: String[] = ["Eggs", "Milk"]
// shoppingList has been initialized with two initial items
 

该shoppingList变量被声明为“String值数组”,用String[ ]编写。因为这个特殊的数组具有指定的String类型值,所以只允许存储String值。在这里,用两个String值初始化(“Eggs”和“Milk”)的shoppingList数组是以数组常值形式编写的。

注:shoppingList数组被声明为一个变量(用var引导器)并不是一个常量(用let引导器),因为还有更多项目要添加在下面的shoppingList例子中。

在这种情况下,数组常值只包含两个String值。这和shoppingList变量声明类型(即数组只包含String的值)相匹配,并允许数组常值以用两个初始项目初始化shoppingList的方式来赋值。

由于Swift中的类型推断,在你将包含相同类型数值的数组常值对其初始化时,你不必写数组类型。shoppingList的初始化可以使用简写形式:

 
var shoppingList: String[] = ["Eggs", "Milk"]
 

由于数组常值的所有数值都是同一类型的,Swift数组推断String[ ]是可以用于shoppingList变量的正确的类型。

访问和修改数组

可以通过相应的修改方法和属性或通过使用下标语法来访问和修改数组。

如查找数组中的项目数,只需查找其只读计量属性:

 
println("The shopping list contains \(shoppingList.count) items.")
// prints "The shopping list contains 2 items."
 

使用简写布尔值isEmpaty来检测计数属性是否等于0:

 
if shoppingList.isEmpty {
println("The shopping list is empty.")
} else {
println("The shopping list is not empty.")
}
// prints "The shopping list is not empty."
 

可以通过调用数组的数组末端追加方法添加一个新的项目:

 
shoppingList.append("Flour")
// shoppingList now contains 3 items, and someone is making pancakes
 

另外,还可用加法赋值运算(+=)将一个新项目添加到数组末尾: </java> shoppingList += "Baking Powder" // shoppingList now contains 4 items </java> 您还可以用加法赋值运算(+=)符为数组添加兼容项目

 
shoppingList += ["Chocolate Spread", "Cheese", "Butter"]
// shoppingList now contains 7 items
 

可利用下标数组值的方法检索,即把你想检索的数值索引用方括号括起来并放在数组名称后面:

 
var firstItem = shoppingList[0]
// firstItem is equal to "Eggs"
 

请注,数组中的第一项的索引为0,不是1。Swift中数组的索引就是0。

你可以用下标语法改写给定索引的数值:

 
shoppingList[0] = "Six eggs"
// the first item in the list is now equal to "Six eggs" rather than "Eggs"
 

你也可以用下标语法即刻改变值的范围,即使替换值和原有值数组长度不同。就像用“Cheese”替换“Chocolate Spread”,用“Banana”和“Apples”替换“Butter”:

 
shoppingList[4...6] = ["Bananas", "Apples"]
// shoppingList now contains 6 items
 

注:不能使用下标语法来添加新项目到数组末尾。如果尝试使用下标语法来检索或设置一个索引值(此为数组现有范围以外的值),这将会引发运行错误。然而,你通过对数组的count属性比较使用一个有效索引。除了当count为0(即数组为空),该数组中的最大有效索引是count-1,因为数组索引从零开始。

插入一个项目到指定索引处的数组,称为数组的insert(atIndex:)方法:

 
shoppingList.insert("Maple Syrup", atIndex: 0)
// shoppingList now contains 7 items
// "Maple Syrup" is now the first item in the list
 

这叫做insert方法,即以索引0指示用shopping list中的Maple Syrup来插入一个新项目。

同样,你可以用removeAtIndex方法从数组中移除此项。此方法可以应用于移除指定索引和返回移除项(如果你不需要它,你可以忽略返回值):

 
let mapleSyrup = shoppingList.removeAtIndex(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
 

当项目被移除的时候,数组不能进行任何编写,所以索引值0此时等同于“Six eggs”:

 
firstItem = shoppingList[0]
// firstItem is now equal to "Six eggs"
 

如果你想从数组中删除最后一个项目,使用removeLast方法而不是removeAtIndex方法以避免需要查询数组的count属性。像removeAtIndex方法,removeLast将返回被删除的项目:

 
let apples = shoppingList.removeLast()
// the last item in the array has just been removed
// shoppingList now contains 5 items, and no cheese
// the apples constant is now equal to the removed "Apples" string
 

迭代数组

你可以用for-in循环方式在数组中迭代整套的数值:

 
for item in shoppingList {
println(item)
}
// Six eggs
// Milk
// Flour
// Baking Powder
// Bananas
 

如果你需要每一项的整数索引和它的值,使用全局枚举函数将数组进行迭代,在由索引和该项目值所组成的数组中,枚举函数为每一项返回一个元组。你可以将元组分解成临时的常量或者变量,作为迭代的一部分。

 
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循环相关信息,请参阅循环语句。

创建并初始化数组

你可以用初始化器语法创建一个特定类型(不设置任何原始值)的空数组:

 
var someInts = Int[]()
println("someInts is of type Int[] with \(someInts.count) items.")
// prints "someInts is of type Int[] with 0 items."
 

注,由于被设置为一种Int[]初始化器的输出,someInt变量的类型会被推断为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[]
 

Swift的数组类型也为创建特定大小的数组提供了一个初始化器,将它所有的值设置成一个既有默认值你将要加入到新数组中的项数(称为count)和适当类型的默认值(称为repeatedValue)传输到初始化器:

 
var threeDoubles = Double[](count: 3, repeatedValue: 0.0)
// threeDoubles is of type Double[], and equals [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 is inferred as Double[], and equals [0.0, 0.0, 0.0, 2.5, 2.5, 2.5]
 

 

字典

字典是储存同一类型多个值的容器。每一个值都与一个独一无二的键相关联,在字典中键充当该值的标示符。不像数组中的项,字典中的项没有特定的指令。当需要查以标示符为基础的数值时,可以使用字典,这跟现实世界中用来查特定单词定义的字典大多相同。

Swift字典特别描述了可以存储的键类型和值类型。它们和Objective-C的NSDictionary和NSMutableDictionary类别不一样,Objective-C的NSDictionary和NSMutableDictionary可以用任何种类的对象作为键和值,并且不提供任何有关这些对象本质的信息。在Swift里面,不管是通过显式类型注释还是通过类型推断,特定字典都可以清晰地储存键类型和数值类型。

Swift的字典类型写为字典<KeyType, valueType>,KeyType可以用作字典键的数值类型,valueType是字典为那些键储存的数值类型。

唯一的局限是KeyType必须是hashable,也就是说,它必须提供一种描绘自我的独特方式。所有的Swift基本类型(比如String、Int、Double和Bool)都默认为是hashable,并且所有这些类型均可作为字典的键。无关联值的枚举成员值(如枚举中所述)也默认为是hashable。

字典常值

你可以用字典常值初始化字典,这和之前见到的数组常值有类似的语法。字典常值是一种将一个或者多个键值对写为Dictionary集合的缩写形式。 一个键值对是键和值的组合。在字典常值中,每一个键值对中的键和值都用冒号隔开。在括号中将键值对写成一个列表,并用逗号隔开。 [ key 1 : value 1 , key 2 : value 2 , key 3 : value 3 ]

下面的例子创建了一个存储国际机场名字的字典。该字典中,这些键是三个字母的国际航空运输协会编码,值是机场名字:

 
var airports: Dictionary<String, String> = ["TYO": "Tokyo", "DUB": "Dublin"]
 

据称,机场字典可以声明为Dictionary类型,即<String,String>,意思是“键为是String型,值也是String型的字典”

注:该airports字典被声明为一个变量(用var引导器)并不是一个常量(用let引导器),因为还有更多airports会出现在下列例子中的字典里。

airports字典用包含两个键值对的字典常值初始化。第一对为“TYO”键和“Tokyo”值。第二对为“DUB”键和“Dublin”值。

本字典常值包含两个String:String对。这和airports变量声明的类型相匹配(一部字典只有一个String键和一个String值),因此字典常值的赋值允许作为用两个初始项初始化airports字典的方式。

至于数组,如果你要用键和值类型一致的字典常量初始化的话,就没必要写下字典的类型。airports的初始值可以使用简写形式:

 
var airports = ["TYO": "Tokyo", "DUB": "Dublin"]
 

因为常值中所有的键都有是相同的类型,同样的所有值也是相同的类型,Swift可以推断Dictionary<String,String>是用作airports字典的正确类型

访问和修改字典

你相应的方法和属性或通过使用下标语法来访问和修改字典。至于数组,你可以通过核对它的只读count属性在Dictionary中找出项目数。

 
println("The dictionary of airports contains \(airports.count) items.")
// prints "The dictionary of airports contains 2 items."
 

你可以用下标语法将新项目添加到字典中。将一种新的适当类型的键用作下标语法,并赋一个新的相应类型的值。

 
airports["LHR"] = "London"
// the airports dictionary now contains 3 items
 

你也可以用下标语法来改变特定键所关联的值。

 
airports["LHR"] = "London Heathrow"
// the value for "LHR" has been changed to "London Heathrow"
 

使用字典的updateValue(forKey:)作为下标的另一种方式,设定或更新特殊键值。如上述下标实例,updateValue(forKey:)方法,如果键不存在就设定一个键值,如果存在一个键就更新它的值。但是不同于下标,updateValue(forKey:)方法,在执行更新操作后会返回旧值。 这让你能够检查更新是否发生。

updateValue(forKey:)方法可以返回字典值类型的可选值。例如,对于存储String值的字典来说,该操作返回String?值或者“可选String”如果值存在且尚未更新,则该可选值包括该键的旧值;如果值不存在就是nil。

 
if let oldValue = airports.updateValue("Dublin International", forKey: "DUB") {
println("The old value for DUB was \(oldValue).")
}
// prints "The old value for DUB was Dublin."
 

你还可以使用下标语法从特定键的字典中来检索值。如果有可能请求值不存在的键的话,字典的下标会返回字典值类型的可选值。如果字典包含请求键的值,下标会返回包含该键已有值的可选值。否则,下标会返回nil:

 
if let airportName = airports["DUB"] {
println("The name of the airport is \(airportName).")
} else {
println("That airport is not in the airports dictionary.")
}
// prints "The name of the airport is Dublin International."
 

你可以使用下标语法,通过为该键赋一个nil值从字典中移除一个键值对。

 
airports["APL"] = "Apple International"
// "Apple International" is not the real airport for APL, so delete it
airports["APL"] = nil
// APL has now been removed from the dictionary
 

或者,通过移除removeValueForKeyd的方法来移除一个键值对。如果值存在,该方法会移除键值对;如果该值不存在,则返回移除的值或nil。

 
if let removedValue = airports.removeValueForKey("DUB") {
println("The removed airport's name is \(removedValue).")
} else {
println("The airports dictionary does not contain a value for DUB.")
}
// prints "The removed airport's name is Dublin International."
 

迭代字典

你可以用for-in循环在字典中迭代键值对。字典的每个项都被还原成(key,value)元组,并且作为迭代的一部分,你可以将元组成员分解成临时常量或变量

 
for (airportCode, airportName) in airports {
println("\(airportCode): \(airportName)")
}
// TYO: Tokyo
// LHR: London Heathrow
 

欲了解更多for-in循环相关信息,请参阅For Loops。

你也可以通过访问keys和values属性来检索字典的键和值的迭代集合。

 
for airportCode in airports.keys {
println("Airport code: \(airportCode)")
}
// Airport code: TYO
// Airport code: LHR
for airportName in airports.values {
println("Airport name: \(airportName)")
}
Airport name: Tokyo
Airport name: London Heathrow
 

如果你需要通过带有数组实例的API来使用字典的键和值,用keys和values属性初始化一个新数组。

 
let airportCodes = Array(airports.keys)
// airportCodes is ["TYO", "LHR"]
let airportNames = Array(airports.values)
// airportNames is ["Tokyo", "London Heathrow"]
 

注:Swift的Dictionary类型为无序集合类型。当迭代没有特别说明的字典时,需要检索键、值和键值对的顺序。

创建一个空字典

至于数组,可以通过初始化器语法来创建一个指定类型的Dictionary。

 
var namesOfIntegers = Dictionary<Int, String>()
// namesOfIntegers is an empty Dictionary<Int, String>
 

该例子创建了一部Int及String型空字典,以存储整型值可读名字。其键为Int类型,其值为String类型。

如果上下文已经提供了类型信息,可以用空字典常值来创建空字典,写为[:](方括号中加一个冒号)

 
namesOfIntegers[16] = "sixteen"
// namesOfIntegers now contains 1 key-value pair
namesOfIntegers = [:]
// namesOfIntegers is once again an empty dictionary of type Int, String
 

注:实际上,Swift数组和字典类型常作为泛型集合执行。欲了解更多泛型类型和集合的相关信息,请参见泛型。

可变性集合

一个单一集合中的数组和字典可以存储多个值。如果你创建一个数组或者一部字典并赋值给变量,创建的集合就会是可变的。这意味着,通过添加更多的项到集

昵    称:
验证码:

相关文档:

swift
IOS实例
ObjectiveC