Swift Dictionary字典
简述
字典就是通过Key - Value对应关系的数据结构。
swift与OC字典区别
类型: Swift字典是值类型, OC字典类型为引用类型
初始化方法
你可以通过如下方式初始化字典。
// 创建一个空字典
init()
// 创建一个最小容量为多少的字典, 一般在你知道接下来字典有多少数量时候使用,注意这里是最小容量,表示字典创建之后,可以超过这个数量,这个只是为了方便为其分配适量内存,避免频繁分配内存,达到内存优化。这个容量值和属性capacity不一定相等。
init(minimumCapacity: Int)
// 从给定序列中创建一个新字典。需要保证键值对的键没有重复的。
init<S>(uniqueKeysWithValues: S)
// 从给定键值序列中创建一个新字典,如果出现键重复,通过闭包处理。
init<S>(S, uniquingKeysWith: (Value, Value) -> Value)
// 从给定序列中按照分组计划创建新字典
init<S>(grouping: S, by: (S.Element) -> Key)
通过uniqueKeyValue初始化 重复键错误
let pairs = [("key1",1),("key2",2), ("key2",2)]
let uniqueKeyDic = Dictionary(uniqueKeysWithValues: pairs)
// Fatal error: Duplicate values for key: 'key2':
通过另外一个初始化方法来解决重复键问题,详情参考数组重复判断。
let pairs = [("key1",1),("key2",2), ("key2",2)]
let uniqueKeyDic = Dictionary(pairs) { (first, second) -> Int in
// return first 保留前一个
// return second 保留后一个
return first + second // 对值进行操作
}
print(uniqueKeyDic) //["key1": 1, "key2": 4]
分组初始化示例
let students = ["Kofi", "Abena", "Efua", "Kweku", "Akosua"]
let studentsByLetter = Dictionary(grouping: students, by: { $0.first! }) // 按照首字母分组
// ["E": ["Efua"], "K": ["Kofi", "Kweku"], "A": ["Abena", "Akosua"]]
print(studentsByLetter) //["K": ["Kofi", "Kweku"], "A": ["Abena", "Akosua"], "E": ["Efua"]]
检查一个字典
isEmpty
是否为空字典
count
字典长度
capacity
不分配新内存情况下,能容纳所有键值对长度
访问Keys和Values
下标
subscript(Key) -> Value
返回某个键的值
subscript(Key, default: () -> Value) -> Value
返回某个键的值,如果不存在,则返回默认值
默认值下标示例
let message = "Hello, Elle!"
var letterCounts: [Character: Int] = [:]
for letter in message {
letterCounts[letter, defaultValue: 0] += 1
}
// letterCounts == ["H": 1, "e": 2, "l": 4, "o": 1, ...]
subscript(Dictionary.Index) -> Dictionary.Element
访问键值对指定位置Index的键值对
index(forKey: Key) -> Dictionary<Key, Value>.Index?
返回键值对index位置
keys
所有键集合
values
所有值的集合
first:(key: Key, value: Value)?
第一个元素的元组
// 返回随机元素元组
func randomElement() -> (key: Key, value: Value)?
// 通过随机算法返回元素
func randomElement<T>(using: inout T) -> (key: Key, value: Value)?
添加Keys和Values
// 更新存在的key下的value值, 如果key不存在,怎添加
func updateValue(Value, forKey: Key) -> Value?
// 合并两个字典。如果有冲突键,则通过闭包解决冲突值的选择。
func merge([Key : Value], uniquingKeysWith: (Value, Value) -> Value)
// 合并键值对到字典中,如果有冲突则通过闭包解决
func merge<S>(S, uniquingKeysWith: (Value, Value) -> Value)
// 创建一个字典,通过何必字典的方式,冲突按照闭包方式解决
func merging([Key : Value], uniquingKeysWith: (Value, Value) -> Value) -> [Key : Value]
// 创建一个字典,来合并键值对和字典,冲突按照闭包方式解决
func merging<S>(S, uniquingKeysWith: (Value, Value) -> Value) -> [Key : Value]
// 预分配指定容量给字典
func reserveCapacity(Int)
移除Keys和Values
// 过滤满足条件的键值对
func filter((Dictionary<Key, Value>.Element) -> Bool) -> [Key: Value]
// 移出某个键的值
func removeValue(forKey: Key) -> Value?
// 根据自定Index移出元素
func remove(at: Dictionary<Key, Value>.Index) -> Dictionary<Key, Value>.Element
// 移出所有键值对, 移出同时是否要保留内存buffer,默认false
func removeAll(keepingCapacity: Bool)
比较字典
==
两个字典相等
!=
两个字典不想等
遍历字典
// 类似for in周期性遍历元素 【与for in不同点, 1.你不可以提前跳出(break, cotinue)遍历 2.闭包内return只会跳出闭包当次,不会跳出外部】
func forEachr((key: Key, value: Value) -> Void)
// 类似数组遍历一样具有下标
func enumerated() -> EnumeratedSequence<Dictioanry<Key, Value>>
不常用
A sequence containing the same elements as this sequence, but on which some operations, such as map and filter, are implemented lazily.
var lazy: LazySequence<Dictionary<Key, Value>>
Returns an iterator over the dictionary’s key-value pairs.
func makeIterator() -> Dictionary<Key, Value>.Iterator
A value less than or equal to the number of elements in the collection.
var underestimatedCount: Int
查找元素
// 返回是否满足给定条件的Bool值
func contains(where:((key: Key, value:Value)) -> Bool) -> Bool
// 返回是否所有元素满足给定条件
func allSatisfy(((key: Key, value: Value)) -> Bool) -> Bool
// 返回第一个满足条件的元素
func first(where: ((key: Key, value: Value)) -> Bool) -> (key: Key, value: Value)?
// 返回第一个满足条件的Index
func firstIndex(where: ((key: Key, value: Value)) -> Bool) -> Index?
// 返回最小元素,在满足给定判断规则情况下(复杂度o(n))
func min(by: ((key: Key, value: Value), (key: Key, value: Value)) -> Bool) -> (key: Key, value: Value)?
// 返回最大元素,在满足给定判断规则情况下(复杂度o(n))
func max(by: ((key: Key, value: Value), (key: Key, value: Value)) -> Bool) -> (key: Key, value: Value)?
min与max示例
----------------min
let hues = ["Heliotrope": 296, "Coral": 16, "Aquamarine": 156]
let leastHue = hues.min { a, b in a.value < b.value }
print(leastHue)
// Prints "Optional(("Coral", 16))"
----------------max
let hues = ["Heliotrope": 296, "Coral": 16, "Aquamarine": 156]
let greatestHue = hues.max { a, b in a.value < b.value }
print(greatestHue)
// Prints "Optional(("Heliotrope", 296))"
转化字典
// 转化字典为另外一个字典, 只能更改值
func mapValues<T>((Value) -> T) -> Dictionary<Key, Value>
// 转化一个字典,并且返回一个数组
func map<T>(((key: Key, value: Value)) -> T) -> [T]
// 返回非空转化后的字典
func compactMap<ElementOfResult>(((key: Key, value: Value)) -> ElementOfResult?) -> [ElementOfResult]
mapValu与map区别
mapValues只转化值,返回数组,闭包内只能获取value
map返回数组,闭包呢可以获取key和value
map与compactMap区别
compactMap转化后不含非空
let data = ["a": "1", "b": "three", "c": "///4///"]
let m: [String: Int?] = data.mapValues { str in Int(str) }
// ["a": 1, "b": nil, "c": nil]
let c: [String: Int] = data.compactMapValues { str in Int(str) }
// ["a": 1]
// 进行归纳法操作,
func reduce<Result>(Result, (Result, (key: Key, value: Value)) -> Result) -> Result
// Returns the result of combining the elements of the sequence using the given closure.
func reduce<Result>(into: Result, (inout Result, (key: Key, value: Value)) -> ()) -> Result
// Returns an array containing the concatenated results of calling the given transformation with each element of this sequence.
func flatMap<SegmentOfResult>(((key: Key, value: Value)) -> SegmentOfResult) -> [SegmentOfResult.Element]
// Returns the elements of the sequence, sorted using the given predicate as the comparison between elements.
func sorted(by: ((key: Key, value: Value), (key: Key, value: Value)) -> Bool) -> [(key: Key, value: Value)]
// 返回打乱顺序的字典(洗牌)
func shuffled() -> [(key: Key, value: Value)]
// 返回指定打乱规则的字典
func shuffled<T>(using: inout T) -> [(key: Key, value: Value)]
集合操作
字典具备位置集合操作的特点。比如各种index,通过inde查找操作等。
比如字典除了通过key下标访问值,还可以通过index来访问
let hues = ["Heliotrope": 296, "Coral": 16, "Aquamarine": 156]
print(hues[hues.startIndex]) //(key: "Coral", value: 16)
print(hues["Coral"]) //Optional(16)
继承遵守
Collection
CustomDebugStringConvertible
CustomReflectable
CustomStringConvertible
CVarArg
Decodable
Conforms when Key
conforms to Decodable
and Value
conforms to Decodable
.
Encodable
Conforms when Key
conforms to Encodable
and Value
conforms to Encodable
.
Equatable
Conforms when Value
conforms to Equatable
.
ExpressibleByDictionaryLiteral
Hashable
Conforms when Value
conforms to Hashable
.
MLDataValueConvertible
Conforms when Key
conforms to MLDataValueConvertible
and Value
conforms to MLDataValueConvertible
.
Sequence
Dictionary与KeyValuePairs区别
通过了解KeyValuePairs到,两者都具有键值对特性。
Dictioanary更关心值和链接关系
KeyValuePairs更关心一堆键值对放在一起,没有其他规则约束它
另外KeayValuePairs允许key重复,key为nil等但是不能直接通过key获取value,不具备字典的快速增删改查。
示例操作
利用字典找出重复元素
算法:给定一个整数数组,判断是否存在重复元素。如果任意一值在数组中出现至少两次,函数返回 true
。如果数组中每个元素都不相同,则返回 false
。(可以简单使用集合判断两者数量是否一致,但是性能不是最好的)
class Soulution {
func containsDuplicate(_ nums: [Int]){
let pairs = nums.map({($0,1)}) //将数组转化为键(数组值为键)值对
let dic = Dictionary(pairs){$0+$1} // 键值对转化为字典,如果有相等的键,则想加附加值
return dic.values.allSatisfy{$0==1} // 所有值是否满足1,(如果有相同值,则会累加1)
}
}