当容器中的元素顺序很重要时,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)