You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中如何让字典内的数组值可变?

Swift中字典内数组的高效修改方案

你遇到的问题本质是Swift的Array是值类型,从字典中取出数组时会生成副本,修改副本不会影响字典内原有的数组。下面是几种无需依赖NSDictionary/NSArray的解决方案:

1. 最简洁的写法:利用下标默认值(Swift 4+)

Swift 4及以上支持给字典下标指定默认值,直接一行代码完成判断、创建(如果需要)和追加操作:

var intsForString = [String:[Int]]()

func add(value: Int, forKey: String) {
    intsForString[forKey, default: []].append(value)
}

add(value: 1, forKey: "a")
add(value: 2, forKey: "a")

print(intsForString["a"]!) // 输出 [1, 2]

这个语法会自动处理key不存在的情况:如果key不存在,先插入空数组到字典,再执行追加;如果key存在,直接对字典内的数组进行修改。得益于Swift的**写时复制(COW)**机制,只有当数组被修改且存在其他引用时才会触发复制,不会产生不必要的性能开销。

2. 兼容旧版本的手动处理方案

如果需要兼容Swift 4以下版本,可以用可选绑定的方式,但同样能借助COW保证效率:

var intsForString = [String:[Int]]()

func add(value: Int, forKey: String) {
    if var ints = intsForString[forKey] {
        ints.append(value)
        intsForString[forKey] = ints
    } else {
        intsForString[forKey] = [value]
    }
}

你担心的“重复查找键、数组复制”问题其实被Swift的COW优化抵消了:取出数组时如果没有其他引用,append操作不会复制数组,修改后存回字典的操作也只会更新一次键值对,性能开销极小。

3. 模拟引用语义:用类包装数组

如果想完全模拟Objective-C中引用类型的行为,可以自己定义一个持有数组的类(类是引用类型):

class WrappedArray<T> {
    var items = [T]()
}

var intsForString = [String:WrappedArray<Int>]()

func add(value: Int, forKey: String) {
    let wrappedArray = intsForString[forKey] ?? WrappedArray<Int>()
    if intsForString[forKey] == nil {
        intsForString[forKey] = wrappedArray
    }
    wrappedArray.items.append(value)
}

这种方式下,字典存储的是类实例的引用,修改wrappedArray.items会直接改变字典内实例的属性,不需要再将数组存回字典。


内容的提问来源于stack exchange,提问作者Thomas Tempelmann

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 21:27:42