Swift编程入门(9)字典

2018/12/20 21:07 下午 posted in  Swift入门

当容器中的元素顺序很重要时,Array类型很有用。
然而顺序不总是很重要。有时候我们只是想在容器中持有一组数据,并在需要时获取信息。这就是字典(dictionary)的使用场景。
Dictionary使用键值对(key-value pair)组织其内容的容器类型。字典的键映射到值。
Dictionary中的键必须是唯一的。这个要求意味着每个键都唯一地映射到对应的值。

创建字典

创建Swift字典的通用语法如下:var dict: Dictionary<Key, Value>。这行代码创建一个Dictionary的可变实例,名叫dict。对字典的键和值接受什么类型的声明位于尖括号(<>)中,这里用Key和Value表示。
对于Swift中Dictionary类型的键,唯一的要求是其必须可散列(hashable):也就是每个Key必须提供一种机制让Dictionary保证任何给定的键都是唯一的。Swift的基本类型都是可散列的,比如String、Int、Float、Double和Bool。
看获得一个Dictionary实例的不同方法.

var dict1: Dictionary<String, Double> = [:] 
var dict2 = Dictionary<String, Double>() 
var dict3: [String:Double] = [:] 
var dict4 = [String:Double]() 

这4种方法得到的是同样的结果:经过完整初始化的Dictionary类型的实例,以及其键值的类型信息。Key被设置为接受String类型的键,而Value被设置为接受Double类型的值。在这4种情况下,字典实例都是空的:没有键也没有值。
[:]和()语法有什么区别呢?本质上是一样的。两者都创建并准备好了Dictionary类型的实例。[:]使用字面量语法创建Dictionary类型的空实例,并且会使用声明中提供的类型信息束键和值。比如说,dict1指定其类型并被初始化为空字典。()语法则使用Dictionary类型的默认初始化方法,这个方法会准备一个空的字典实例。本书后面部分会详细介绍初始化方法。

初始化字典

var movieRatings = ["Donnie Darko": 4, "Chungking Express": 5, "Dark City": 4]

访问和修改字典

获取字典的元素个数

import Cocoa 
var movieRatings = ["Donnie Darko": 4, "Chungking Express": 5, "Dark City": 4] 
print("I have rated \(movieRatings.count) movies.")

使用字典的count属性

读取值

import Cocoa 
var movieRatings = ["Donnie Darko": 4, "Chungking Express": 5, "Dark City": 4] 
print("I have rated \(movieRatings.count) movies.") 
let darkoRating = movieRatings["Donnie Darko"]

修改值

import Cocoa 
var movieRatings = ["Donnie Darko": 4, "Chungking Express": 5, "Dark City": 4] 
print("I have rated \(movieRatings.count) movies.") 
let darkoRating = movieRatings["Donnie Darko"] 
movieRatings["Dark City"] = 5 
movieRatings

更新值

还有一种有用的方式可以更新与字典的键相关联的值:updateValue(_:forKey:)方法。这
个方法接受两个参数:value: Value和forKey: Key。第一个参数value接受新的值,第二个
参数forKey指定哪个键需要改变值。
这个方法之所以有用,是因为它能保存该键之前映射的值。还有个小小的警告:updateValue(_:forKey:)返回可空类型。这种返回类型很方便,因为这个键可能在字典中不存在。因此,把updateValue(_:forKey:)的返回值赋给一个预期类型的可空实例,并用可空实例绑定来获取这个键的旧值会很有用。

import Cocoa 
var movieRatings = ["Donnie Darko": 4, "Chungking Express": 5, "Dark City": 4] 
print("I have rated \(movieRatings.count) movies.") 
let darkoRating = movieRatings["Donnie Darko"] 
movieRatings["Dark City"] = 5 
movieRatings 
let oldRating: Int? = movieRatings.updateValue(5, forKey: "Donnie Darko") 
if let lastRating = oldRating, let currentRating = movieRatings["Donnie Darko"] { 
print("Old rating: \(lastRating); current rating: \(currentRating)") 
}

增加值

movieRatings["The Cabinet of Dr. Caligari"] = 5

这里用语法movieRatings["The Cabinet of Dr. Caligari"] = 5给字典增加了新的键值对。赋值运算符将值(本例中是5)关联到了新键("The Cabinet of Dr. Caligari"上。

删除值

movieRatings.removeValue(forKey: "Dark City")

removeValue(forKey:)方法接受一个键作为参数,将与其匹配的键值对删除。

把一个键的值设为nil

movieRatings["Dark City"] = nil

结果在本质上和删除一样的,但是这样写不会返回被删除键的值。

循环

遍历字典

for (key, value) in movieRatings { 
    print("The movie \(key) was rated \(value).") 
}

只访问键

for movie in movieRatings.keys { 
    print("User has rated \(movie).") 
}

不可变字典

创建不可变字典和创建不可变数组差不多,用let关键字告诉Swift编译器这个Dictionary实例不可变。

let album = ["Diet Roast Beef": 268, 
            "Dubba Dubbs Stubs His Toe": 467, 
            "Smokey's Carpet Cleaning Service": 187, 
            "Track 4": 221] 

把字典转换为数组

有时候把字典中的信息取出并放入数组会很有用。合理的做法是用字典的键创建一个Array.

let watchedMovies = Array(movieRatings.keys)