我注意到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:)
方法,因此
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
如果 无法 执行附加操作,则返回):
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
问题内容: 我很沮丧,我不知道该怎么做。 基本上,我只想创建一个表,但是如果它存在,则需要将其删除并重新创建,而不是将其截断,但是如果不存在,则可以创建它。 有人可以帮忙吗? 谢谢乔治 问题答案: 放在tablename您的发言之前。 该语句将删除该表(如果存在),但如果不存在则不会引发错误。
这是我的代码: 每次执行程序时,我都会创建一个新文档,我只想在不存在的情况下创建它,如果文档存在,只需添加内容即可。
问题内容: 我有一个钥匙型课。让我们称为map的实例。 我要添加{ ,}(是的一个实例,并且一)该地图。但是,如果键已经存在,我想求和该映射图中的当前值。 目前我使用 但是在Java 8中是否有一种时髦的方式来做到这一点,例如使用和? 遗憾的是我无法弄清楚。 谢谢。 问题答案: 这就是地图上的合并功能的作用。 这可以进一步减少到 它基本上等于
问题内容: Python是否有任何内置功能可将数字添加到文件名(如果已存在)? 我的想法是,它将按某些OS的工作方式工作-如果将文件输出到已经存在该名称文件的目录中,则它将添加数字或对其进行递增。 即:如果“ file.pdf”存在,它将创建“ file2.pdf”,并下次创建“ file3.pdf”。 问题答案: 从某种意义上说,Python在模块中内置了此功能。不幸的是,您必须利用私有全局变量
问题内容: 我的研究和实验还没有得到答案,所以我希望能有所帮助。 我正在修改一个应用程序的安装文件,该应用程序在以前的版本中没有我想立即添加的列。我不想手动添加列,而是要在安装文件中并且仅在表中不存在新列的情况下才添加。 该表如下创建: 如果我在create table语句下面添加以下内容,那么我不确定如果该列已经存在(可能已填充)会发生什么情况: 因此,我尝试了在某处找到的以下内容。这似乎不起作
问题内容: 我正在使用PostgreSQL,并且是SQL的初学者。我正在尝试从查询创建表,并且如果运行: 它工作正常。但是然后如果我添加“如果不存在”并运行: 使用完全相同的查询,我得到: 有什么办法吗? 问题答案: CREATE TABLE AS被认为是与普通CREATE TABLE 分开的语句,并且 直到Postgres版本9.5 (请参阅changelog条目)不支持子句 为止 。(请务必查