swift笔记(2)

Swift 提供两种集合类型来存储集合,数组和字典。数组是一个同类型的序列化列表集合。字典是一个能够使用类似于键的唯一标识符来获取值的非序列化集合。

下面的例子创建一个叫shoppinglist,储存字符串(String)类型的数组。

1
2
var shoppingList: String[] = ["Eggs", "Milk"]
// 使用两个初始化参数来初始化shoppingList

shoppingList数组是被定义为一个变量(使用var  标识符 )而不是常量(使用let 标识符)

当你用相同类型的值来初始化时,你可以不写明类型。初始化shoppingList可以用下面这个方法来代替。

1
var shoppingList = ["Eggs", Milk"]

在数组末尾增加一个元素可以通过append方法

1
2
shoppingList.append("Flour")
// shoppingList 现在包含3个元素

甚至,还可以用(+=)操作符来把一个元素添加到数组末尾

1
2
shoppingList += "Baking Powder"
// shoppingList 现在包含4个元素

你也可以用(+=)操作符来把一个数组添加到另一个数组的末尾

1
2
shoppingList += ["Chocolate Spread", "Cheese", "Butter"]
// shoppingList 现在包含7个元素

从数组中取出一个值可以使用下标语法。如果你知道一个元素的索引值,你可以数组名后面的中括号中填写索引值来获取这个元素

1
2
var firstItem = shoppingList[0]
// firstItem 等于 “Eggs"

注意,数组的第一个元素的索引值为0,不为1,Swift的数组总是索引0;

你可以使用下标语法通过索引修改已经存在的值。

1
2
shoppingList[0] = "Six eggs"
//列表中的第一个值等于"Six eggs" 而不等于 “Eggs"

你可以使用下标语法一次性改变一系列的值,尽管修改的区域远远大于要修改的值。在下面的雷子中, 替换掉 “Chocolate Spread”, “Cheese”,”Butter”,”Bananas”,”Apples”:

1
2
shoppingList[4...6] = ["Bananas", "Apples"]
// shoppingList 现在包含6个元素

在一个特定的索引位置插入一个值,可以使用insert(atIndex:)方法

1
2
3
shoppingList.insert("Maple Syrup", atIndex: 0)
// shoppingList 现在包含7个元素
// "Maple Syrup" 在数组的第一位

这里调用insert方法指明在shoppingList的索引为0的位置中插入一个新元素 “Maple Syrup”

同理,你可以调用removeAtIndex方法移除特定的元素。这个方法移除特定索引位置的元素,已经返回这个被移除的元素(尽管你并不关心这个返回值)。

1
2
3
4
let mapleSyrup = shoppingList.removeAtIndex(0)
// 索引位置为0的元素被移除 
// shoppingList 现在包含6个元素, 不包括 Maple Syrup
// mapleSyrup 常量等于被移除的 "Maple Syrup" 字符串

当元素被移除的,数组空缺的位置将会被填补,所以现在索引位置为0的元素再一次等于”Six eggs”:

1
2
firstItem = shoppingList[0]
// firstItem 现在等于 "Six eggs”

如果你从数组中移除最后一个元素,使用removeLast方法比removeAtIndex更方便,因为后者需要通过count属性计算数组的长度。和removeAtIndex方法一样,removeLast会返回被移除的元素。

1
2
3
4
let apples = shoppingList.removeLast()
//元素的最后一个元素被移除
// shoppingList 现在包含5个元素,不包括 cheese
// apples 常量 现在等于被移除的 "Apples" string

遍历数组
可以使用for-in循环来遍历数组中的值

1
2
3
4
5
6
7
for item in shoppingList {     println(item)
}
// Six eggs
// Milk
// Flour
// Baking Powder
// Bananas

如果需要每一个元素的整形的索引值,使用enumerate函数代替会更方便,enumerate函数对于每一个元素都会返回一个包含元素的索引和值的元组(tuple)。你可以在遍历部分分解元祖并储存在临时变量或者常量中。

1
2
3
4
5
6
7
for (index, value) in enumerate(shoppingList) {     println("Item \(index + 1): \(value)")
}
// 元素 1: Six eggs
// 元素 2: Milk
// 元素 3: Flour
// 元素 4: Baking Powder
// 元素 5: Bananas

创建和初始化数组
创建一个空的数组和确定的类型(不包含初始化值)使用的初始化语法:

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

注意,someInt变量被确定为Int[],因为它使用生成Int[]的初始化方法。

或者,如果上下文(context)已经提供类型信息,例如函数参数或者已经确定类型的常量和变量,你可以从空的数组实量(Array Literals)创建一个空数组,写作[](空的中括号对)。

1
2
3
4
someInts.append(3)
// someInts 现在包含1个Int型的元素
someInts = []
// someInts 现在是一个空的数组, 但是类型仍然为Int[];

Swift数组类型也提供初始化方法来创建确定长度和提供默认数值的数组。你可以通过这个初始化方法增加一个新的数组,元素的数量成为count,合适的默认值为repeatedValue

1
2
var threeDoubles = Double[](count: 3, repeatedValue: 0.0)
// threeDoubles 的类型为 Double[], 以及等于 [0.0, 0.0, 0.0]

得益于类型推断,你并不需要指明这个数组储存的类型就能使用这个初始化方法,因为它从默认值中就能推断出来。

1
2
var anotherThreeDoubles = Array(count: 3, repeatedValue: 2.5)
// anotherThreeDoubles 被推断为 Double[], 以及等于 [2.5, 2.5, 2.5]

Swift的字典写法是Dictionary<KeyType,ValueType>,KeyType是你想要储存的键,ValueType是你想要储存的值。

唯一的限制就是KeyType必须是可哈希的(hashable)——就是提供一个形式让它们自身是独立识别的。Swift的所有基础类型(例如字符串(String),整形(Int),双精度(Double)和布尔(Bool))在默认是可哈希的(hashable),和这些类型都常常用语当作字典的键。枚举成员值不需要协助值(associated values)(具体描述在 Enumerations)也是因为它们默认也是可哈希的(hashable)。

字典实量(Dictionary Literals)
你可以直接用一个字典实量(Dictionary Literals)初始化一个字典。和前面定义一个数组实量(Array Literals)的语法一样。字典实量(Dictionary Literals)就是使用简略写法直接写一个或者多个的键值对来定义一个字典。

一个键值对是一个键和值的组合。在字典实量(Dictionary Literals)里面,每一个键值对总是用一个冒号把键和值分割。键值对的写法就想是一个列表,使用逗号分割,并被一对中括号[]包含着:

1
[key 1: value 1, key 2: value 2, key 3: value 3]

在下面的例子,将会创建一个字典来储存国际机场的名字。在这个字典里面,键是三个字的国际航空运送协会代码,以及它的值是机场的名称:

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

airport字典被定义为一个类型为Dictionary<String, String>,这意味这,这个字典的键类型是字符串String,和它的值的类型也是String。

注意
airport字典是被定义为一个变量(使用var 标识符)而不是常量(使用let 标识符),所以在下面的例子可以直接添加元素。

airport字典使用一个包含两个键值对的字典实量(Dictionary Literals)来初始化。第一对由一个叫“TYO”的键和一个叫“Tokyo”的值,第二对有一个叫“DUB”的键和一个叫“Dublin”的值。

这个字典实量(Dictionary Literals)包含两个字符串(String):字符串对。这符合airport变量定义的类型(一个字典只包括字符串(String)键和字符串(String)值),所以在分配字典实量(Dictionary Literals)的时候被允许作为airport字典的两个初始化元素。

和数组一样,如果你初始化一个字典的时候使用相同的类型,你可以不指明字典的类型。
airport初始化可以用下面这个简略写法来代替:

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

因为所有的键在字面上都是相同的类型,同样,所有的值也是同样的类型,所以Swift可以推断为Dictionary<String, String>是airports字典的正确类型。

读取和修改字典
你可以通过属性,方法或者下标来读取和修改字典。和数组一样,你使用只读的count属性来检查字典(Dictionary)包含多少个元素。

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

你可以使用下标语法给一个字典添加一个元素。使用合适类型作为新的键,并分配给它一个合适的值

1
2
 airports["LHR"] = "London"
//  airports dictionary 现在有 3 items

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

1
2
airports["LHR"] = "London Heathrow"
//"LHR" 的值已经被改变为 "London Heathrow"

同样, 使用字典的updateValue(forKey:) 方法去设置或者更新一个特定键的值 . 和上面的下标例子一样, updateValue(forKey:) 方法如果键不存在则会设置它的值,如果键存在则会更新它的值, 和下标不一样是, updateValue(forKey:) 方法 如果更新时,会返回原来旧的值rThis enables you to 可以使用这个来判断是否发生了更新。

1
2
3
4
5
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

1
2
3
4
5
6
 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,来移除这个键值对。

1
2
3
airports["APL"] = "Apple International"
// "Apple International" 不是 APL的真实机场,所以删除它
airports["APL"] = nil

// APL 已经从字典中被移除
同样,从一个字典中移除一个键值对可以使用removeValueForKey方法,这个方法如果存在键所对应的值,则移除一个键值对,并返回被移除的值,否则返回nil。

1
2
3
4
5
6
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循环来遍历字典的键值对。字典中的每一个元素都会返回一个元祖(tuple),你可以在循环部分分解这个元祖,并用临时变量或者常量来储存它。

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

更多有关for-in 循环的信息, 参见 For Loops.
你也可以读取字典的keys属性或者values属性来遍历这个字典的键或值的集合。

1
2
3
4
5
6
7
8
9
10
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

如果你需要一个接口来创建一个字典的键或者值的数组实例,你可以使用keys或者values属性来初始化一个数值。

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

注意
Swift中的字典类型是非序列化集合,如果你需要序列化取回键,值,或者键值对,遍历字典不具体叙述。

创建一个空字典
字典一样,你可以使用确定类型的语法创建一个空的字典。

1
2
var namesOfIntegers = Dictionary<Int, String>()
// namesOfIntegers 是一个空的 Dictionary<Int, String> 类型的字典

这个例子创建一个Int,String类型的字典来储存可读性较好的整数值。它的键是Int类型,以及它们的值是String类型。
如果 上下文(context )中已经提供类型信息,可用一个字典实量(Dictionary Literal)创建一个空的字典,写作[;](由一对[]包含一个冒号:)

1
2
3
4
namesOfIntegers[16] = "sixteen"
// namesOfIntegers现在包含1 个键值对
namesOfIntegers = [:]
// namesOfIntegers 是一个类型为Int, String的空字典

注意
在这个场景,Swift数组和字典类型是一个内置的集合。更多的内置类型和集合参见Generics

3、可变集合类型

数组和字典都是在一个集合中一起储存不同的变量.如果你创建一个数组或者字典,再包含一个变量,创建的这个变量被称为可变的(mutable) 这意味这,你可以在创建之后增加更多的元素来改变这个集合的长度,或者移除已经包含的。 相反的, 如果你把一个数组或者字典定义为常量,则这个数组或者字典不是可变的,他们的长度并不能被改变。
字典中,不可变也意味着你不能替换已经存在的键的值。一个不可变字典,一旦被设置就不能改变。
数组的不可变有一点点的不同。然而,你仍然不能做任何有可能修改不可变数组的行为。但是你可以重新设置一个已经存在的索引,这使得当Swift的数组的长度确定时,能更好地优化数组的性能。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值