Swift | Dictionary
Posted 忧郁的思想家
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Swift | Dictionary相关的知识,希望对你有一定的参考价值。
“
Are unordered collections of key-value pairs.
The keys are all of the same type, and the values are all of the same type.
Use subscripting to get values and to add, update or remove pairs.
If a key is not in a dictionary, lookup returns nil.
The key of a dictionary must be a type that conforms to the Hashable protocol.
Basic Swift types such as String, Int, Double are Hashable out of the box.
”
01
—
Dictionary
- 字典储存无序的互相关联的同一类型的键和同一类型的值的集合(键值对)
- 字典类型的全写方式 Dictionary<Key, Value>,简写方式 [Key: Value],建议使用简写方式
- 字典的key必须是可哈希的(Hashable) String, Int, Double, Bool等Swift的基本类型都是Hashable
字典其实是哈希表。字典通过键的hashValue来为每个键在其底层作为存储的数组上指定一个位置。这也就是Dictionary要求它的Key类型需要遵守Hashable 协议的原因。标准库中所有的基本数据类型都是遵守Hashable协议的,它们包括字符串,整数,浮点数以及布尔值。另外,像是数组,集合和可选值这些类型,如果它们的元素都是可哈希的,那么它们自动成为可哈希的。
为了保证性能,哈希表要求存储在其中的类型提供一个良好的哈希函数,也就是说这个函数不会产生太多的冲突。实现一个在整个整数范围内均匀分布其输入的良好的哈希函数并不容易。不过幸运的是我们几乎不需要自己实现这个函数。在很多情况下,编译器可以生成 Hashable 的实现,即使它不适用于某个特定类型,标准库也带有让自定义类型可以挂钩的内置哈希函数。
02
—
API
创建字典
- 初始化器
- 简写方式
- 字面量 [key 1: value 1, key 2: value 2, key 3: value 3]
- Sequence
//创建空字典
var dict1 = Dictionary<String,Int>()
var dict2 = [String:Int]()
var dict3:Dictionary<String,Int> = [:]
var dict4:[String:Int] = [:]
//字面量创建字典
let dict = ["zhangsan":18,"lisi":20,"xiaoming":16]
print(dict)
var a = Dictionary<String,Int>(dictionaryLiteral: ("one",1),("two",2),("three",3))
print(a)
//通过序列
var cities = ["Delhi", "Bangalre", "Hyderabad"]
var distance = [2000, 10, 620]
let cityDistanceDict = Dictionary(uniqueKeysWithValues: zip(cities, distance))
print(cityDistanceDict) //["Delhi": 2000, "Hyderabad": 620, "Bangalre": 10]
常用属性 count,isEmpty
可以使用count只读属性来找出Dictionary拥有多少元素(O(n) 需要循环)
使用布尔量isEmpty属性检查字典是否为空(O(1))
var dict = ["zhangsan":18,"lisi":20,"xiaoming":16]
print(dict.count)
print(dict.isEmpty)
dict.reserveCapacity(10) //当你知道字典将有多少个元素时,设置Capacity可以提高性能
遍历字典
1.For-In 循环
2.可以通过访问字典的 keys 和 values 属性来取回可遍历的字典的键或值的集合
3.Swift的Dictionary类型是无序的。要以特定的顺序遍历字典的键或值,使用键或值的sorted() 方法
var dict = ["zhangsan":18,"lisi":20,"xiaoming":16]
for item in dict{
print(item) //(key:xxx,value:xxxx)
}
for (key,value) in dict{
print("\(key):\(value)")
}
print(dict.keys)
print(dict.values)
for (key,value) in dict.sorted(by: { $0.value > $1.value}){
print("\(key):\(value)")
}
for key in dict.keys.sorted(){
print("\(key):\(dict[key] ?? 0)")
}
字典的常用操作
获取元素
1. subscript(key: Key) 通过key获取元素,返回的是可选型
2. subscript(key: Key, default defaultValue: @autoclosure () -> Value) -> Value 通过key获取元素,如果不存在则返回defaultValue的执行结果
var dict = ["English":98,"Math":100,"History":95]
print(dict["ios"]) //nil
print(dict["English"]) //Optional(98)
print(dict["ios",default:10]) //10
添加或者更新元素
1.使用下标添加或者更新元素
2.使用updateValue(_:forKey:) 方法添加或更新元素,返回一个字典值类型的可选项值
var dic:[String:Int] = [:]
dic["xiaoming"] = 20
dic["lisi"] = 21
print(dic) //["lisi": 21, "xiaoming": 20]
print(dic.updateValue(30, forKey: "xiaoming") ?? "不存在") // 20
print(dic) //["lisi": 21, "xiaoming": 30]
移除元素
1.使用下标脚本语法给一个键赋值nil,来从字典当中移除一个键值对
2.使用removeValue(forKey:)来从字典里移除键值对。这个方法移除键值对如果他们存在的话,并且返回移除的值,如果值不存在则返回nil 。
(当字典中存储的可选类型,dic["key"] = nil总是移除元素,而不是将可选类型的值设置为nil,如果想要赋值为nil,可以使用updateValue方法)
var dic = ["zhangsan":18,"lisi":20,"xiaoming":16]
dic["xiaoming"] = nil
print(dic) //["zhangsan": 18, "lisi": 20]
print(dic.removeValue(forKey: "lisi")) //Optional(20)
print(dic) //["zhangsan": 18]
合并两个字典
1. merge(_:uniquingKeysWith:)
它接受两个参数,第一个是要进行合并的键值对,第二个是定义如何合并相同键的两个值的函数。
2.mapValues 将字典的值进行转换,返回一个新的字典
var dictionary1 = ["①":1,"②":2]
var dictionary2 = ["⑤":5,"⑩":10,"②":20]
dictionary1.merge(dictionary2) { (_, new) -> Int in return new } //这里保存新值
print(dictionary1) //["⑤": 5, "②": 20, "①": 1, "⑩": 10]
//mapValues
print(dictionary1.mapValues{String($0)}) //["⑩": "10", "①": "1", "②": "20", "⑤": "5"]
firstIndex
- 虽然字典是无序的,但是每个kv对在扩容之前的位置是稳定的。如果你需要保持顺序的kv对 可以使用 KeyValuePairs
let imagePaths = ["star":"/glyphs/star.png",
"spacer":"/sbin/spacer.image",
"new":"/index/potial/new.html"]
let index = imagePaths.firstIndex { $0.value.hasPrefix("/index") }
if let i = index{
print(i)
print(imagePaths[i])
//Index(_variant: Swift.Dictionary<Swift.String, Swift.String>.Index._Variant.native(Swift._HashTable.Index(bucket: Swift._HashTable.Bucket(offset: 0), age: 115200514)))
}else{
print("Not found!")
}
KeyValuePairs
- KeyValuePairs:当需要顺序存储键值对并且不需要快速查找关键值对应的值时,可以使用该类型的实例对象,当使用该类型时,key和value都不要求是Hashable类型的
- 使用创建Dictionary的语法创建KeyValuePairs,除了保持键值对有序外,KeyValuePairs还允许出现重复的key
let recordTimes:KeyValuePairs = ["Flor":10.89,
"younfas":10.22,
"younfas":11,
"hollo":9.89]
print(recordTimes)
print(recordTimes.first!)
//print(recordTimes[2]) //(key: "younfas", value: 11.0)
03
—
性能
访问元素:O(1)
插入元素:O(1)
删除元素:O(1)
查找元素:O(1)
以上是关于Swift | Dictionary的主要内容,如果未能解决你的问题,请参考以下文章
swift里nsdictionary和dictionary有啥区别