我注意到Swift中的一个常见模式是
var x:[String:[Thing]] = [:]
因此,当您想“将一项添加到数组之一”时,您不能只
x[which].append(t)
你必须
if x.index(forKey: which) == nil { x[which] = [] } x[which]!.append(s!)
真的,有没有更快捷的方式来表达类似
x[index?!?!].append??(s?!)
(请注意,显然您可以为此使用扩展名;这是关于Swiftiness的问题。)
Swift 4更新:
从Swift 4开始,字典有一种subscript(_:default:)方法,因此
subscript(_:default:)
dict[key, default: []].append(newElement)
追加到已经存在的数组或空数组。例:
var dict: [String: [Int]] = [:] print(dict["foo"]) // nil dict["foo", default: []].append(1) print(dict["foo"]) // Optional([1]) dict["foo", default: []].append(2) print(dict["foo"]) // Optional([1, 2])
从 Swift 4.1 (当前处于beta版)开始,这也 _很快 比较Hamish的评论。
除了编写的内容外,您还可以使用nil-coalescing运算符
dict[key] = (dict[key] ?? []) + [elem]
或可选链接(nil如果 无法 执行附加操作,则返回):
nil
if dict[key]?.append(elem) == nil { dict[key] = [elem] }
正如SE-0154在“提供字典键和值的自定义集合”中以及 @Hamish在注释中提到的那样,这两种方法均会复制数组。
使用SE-0154的实现,您将能够在不创建副本的情况下更改字典值:
if let i = dict.index(forKey: key) { dict.values[i].append(elem) } else { dict[key] = [key] }
目前,最有效的解决方案由Rob Napier在Swift中的Dictionary中使用MutableArray提供,因为值执行速度非常慢?如何优化或正确构建
var array = dict.removeValue(forKey: key) ?? [] array.append(elem) dict[key] = array
一个简单的基准确认“ Rob的方法”是最快的:
let numKeys = 1000 let numElements = 1000 do { var dict: [Int: [Int]] = [:] let start = Date() for key in 1...numKeys { for elem in 1...numElements { if dict.index(forKey: key) == nil { dict[key] = [] } dict[key]!.append(elem) } } let end = Date() print("Your method:", end.timeIntervalSince(start)) } do { var dict: [Int: [Int]] = [:] let start = Date() for key in 1...numKeys { for elem in 1...numElements { dict[key] = (dict[key] ?? []) + [elem] } } let end = Date() print("Nil coalescing:", end.timeIntervalSince(start)) } do { var dict: [Int: [Int]] = [:] let start = Date() for key in 1...numKeys { for elem in 1...numElements { if dict[key]?.append(elem) == nil { dict[key] = [elem] } } } let end = Date() print("Optional chaining", end.timeIntervalSince(start)) } do { var dict: [Int: [Int]] = [:] let start = Date() for key in 1...numKeys { for elem in 1...numElements { var array = dict.removeValue(forKey: key) ?? [] array.append(elem) dict[key] = array } } let end = Date() print("Remove and add:", end.timeIntervalSince(start)) }
1000键/ 1000元素的结果(在1.2 GHz Intel Core m5 MacBook上):
您的方法:0.470084965229034 零合并:0.460215032100677 可选链接0.397282958030701 删除并添加:0.160293996334076
对于1000个键/ 10,000个元素:
您的方法:14.6810429692268 零合并:15.1537700295448 可选链接14.4717089533806 删除并添加:1.54668599367142