加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Swiftier Swift用于“添加阵列,或者如果不存在则创建……”

发布时间:2020-12-14 04:36:02 所属栏目:百科 来源:网络整理
导读:我注意到 Swift中的一个常见模式是 var x:[String:[Thing]] = [:] 所以,当你想“将一个项目添加到其中一个数组”时,你不能只是 x[which].append(t) 你必须 if x.index(forKey: which) == nil { x[which] = [] }x[which]!.append(s!) 真的,有一种更快捷的说法
我注意到 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?!)

>虽然这是一个关于样式的问题,但由于Swift的复制性,在触摸Swift中的数组时,性能似乎是一个关键问题.

(请注意,显然你可以使用扩展名;这是一个关于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(目前处于测试版)开始,这也很快,
比较Hamish的评论here.

以前的答案为Swift< = 3:据我所知 - 没有办法“创建或更新”字典
使用单个下标调用的值.

除了你写的内容,你可以使用nil-coalescing运算符

dict[key] = (dict[key] ?? []) + [elem]

或可选链接(如果追加操作,则返回nil
无法执行):

if dict[key]?.append(elem) == nil {
     dict[key] = [elem]
}

正如SE-0154 Provide Custom Collections for Dictionary Keys and Values中提到的那样,也是@Hamish在评论中提到的两种方法
制作一个数组的副本.

随着SE-0154的实施,您将能够变异
没有复制的字典值:

if let i = dict.index(forKey: key) {
    dict.values[i].append(elem)
} else {
    dict[key] = [key]
}

目前,Rob Napier提供了最有效的解决方案
在Dictionary in Swift with Mutable Array as value is performing very slow? How to optimize or construct properly?:

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上):

Your method:      0.470084965229034
Nil coalescing:   0.460215032100677
Optional chaining 0.397282958030701
Remove and add:   0.160293996334076

对于1000个键/ 10,000个元素:

Your method:      14.6810429692268
Nil coalescing:   15.1537700295448
Optional chaining 14.4717089533806
Remove and add:   1.54668599367142

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读