SwiftNote-Dictionary

1,046 阅读3分钟

字典 Dictionary

  • 字典存储无序的互相关联的同一类型的键和同一类型的值的集合
  • 字典类型的全写方式 Dictionary<Key, Value>,简写方式[Key, Value],建议使用简写方式
  • 字典的 key 必须是可哈希的

创建空字典

  • 初始化器方式 var dict1 = Dictionary<String, Int>()

  • 简写方式 var dict2 = [String, Int]()

  • 字面量方式

    var dict3 = Dictionary<String, Int> = [:]
    let dict = ["zhangsan": 18, "lisi": 20, "wangwu": 30]
    

可以使用 count 只读属性来找出字典用于多少个元素 使用布尔量 isEmpty 属性检查字典是否为空

遍历字典

  • for-in 循环

  • 可以通过访问字典的 keysvalues 属性来获取可遍历字典的键或者值的集合

  • Swift 的 Dictionary 类型是无序的。要以特定的顺序遍历字典的键或值,使用键或值的 sorted() 方法

    let dict = ["zhangsan": 18, "lisi": 20, "wangwu": 30]
    for (key, value) in dict {
        print("name:\(key), age\(value)")
    }
    // name:lisi, age20
    // name:zhangsan, age18
    // name:wangwu, age30
    for key in dict.keys.sorted() {
        print("name:\(key), age\(dict[key] ?? 25)")
    }
    // name:lisi, age20
    // name:wangwu, age30
    // name:zhangsan, age18
    for (offset, element) in dict.enumerated() {
        print("offset:\(offset), element:\(element)")
    }
    // offset:0, element:(key: "wangwu", value: 30)
    // offset:1, element:(key: "lisi", value: 20)
    // offset:2, element:(key: "zhangsan", value: 18)
    

添加/更新元素

  • 使用下标添加或更新元素

  • 使用 updateValue(_:forKey:) 方法添加或更新元素,返回一个字典值类型的可选值,若是新增的键值对,那么返回值为 nil,若是修改已经存在的 key 对应的 value,则返回修改前的 value

    var dict = ["zhangsan": 18]
    dict["lisi"] = 20
    print(dict) // ["zhangsan": 18, "lisi": 20]
    let item = dict.updateValue(30, forKey: "wangwu")
    print(dict) // ["wangwu": 30, "zhangsan": 18, "lisi": 20]
    print(item) // nil
    let item1 = dict.updateValue(35, forKey: "wangwu")
    print(dict)  // ["zhangsan": 18, "lisi": 20, "wangwu": 35]
    print(item1) // Optional(30)
    

移除元素

  • 使用下标脚本语法对一个键赋值 nil 来从字典中移除一个键值对

  • 使用 removeValue(forKey:) 来从字典中移除一个键值对。若要移除的键值对存在则返回移除的键值对,若不存在则返回 nil

    var dict = ["zhangsan": 18, "lisi": 20, "wangwu": 30]
    dict["zhangsan"] = nil
    print(dict) // ["lisi": 20, "wangwu": 30]
    let item = dict.removeValue(forKey: "lisi")
    print(dict) // ["wangwu": 30]
    print(item) // Optional(20)
    

合并两个字典

  • 调用 merge(_:uniquingKeysWith:) 方法来合并字典。

    var fruit = ["apple": 10, "orange": 12]
    let dict = ["apple": 5, "peach": 2]
    fruit.merge(dict) { (current, _) -> Int in
        current
    }
    // 如果有相同的 key 存在,采用第一个字典中的值作为合并后该 key 的值
    print(fruit) // ["peach": 2, "apple": 10, "orange": 12]
    
    var fruit = ["apple": 10, "orange": 12]
    let dict = ["apple": 5, "peach": 2]
    fruit.merge(dict) { (_, added) -> Int in
        added
    }
    // 如果有相同的 key 存在,采用后一个字典中的值作为合并后该 key 的值
    print(fruit) 
    // ["peach": 2, "orange": 12, "apple": 5]
    

firstIndex

虽然字典是无序的,但是每个 kv 对在扩容之前的位置是稳定的。如果你需要保持顺序的 kv 对可以使用 KeyValuePairs

let imagePaths = ["star": "/glyphs/star.png",
                  "portrait": "images/content/portrait.png",
                  "spacer": "images/shared/spacer.png"]
let glyphIndex = imagePaths.firstIndex { (key, value) -> Bool in
    value.hasPrefix("/glyphs")
}
if let index = glyphIndex {
    print(index)
    print("the '\(imagePaths[index].key)' image is a glyph.")
} else {
    print("No glyphs found!")
}
// Index(_variant: Swift.Dictionary<Swift.String, Swift.String>.Index._Variant.native(Swift._HashTable.Index(bucket: Swift._HashTable.Bucket(offset: 3), age: -1037599221)))
// the 'star' image is a glyph.
let recordTimes: KeyValuePairs = ["James": 10.21,
                                  "Durant": 10.87,
                                  "Rose": 10.23,
                                  "Russel": 10.43]
print(recordTimes.first)
// Optional((key: "James", value: 10.21))