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

Swift字典比较优化:无需转数组即可排除指定键的实现方案

解决Swift字典比较扩展直接接受Dictionary.Keys参数的问题

我帮你调整这个Dictionary扩展,让它可以直接接收car.keys这类Dictionary.Keys类型的参数,不用再手动转成Array。先拆解下问题核心:

你当前的扩展里,excluding参数的类型是固定数组[Key],但car.keys返回的是Dictionary.Keys——这是Swift字典自带的自定义序列类型,并非Array,所以直接传入会触发类型不匹配的编译错误。要解决这个问题,只需要把参数类型放宽到任意遵循Sequence协议的Key序列即可。

修改后的扩展代码

extension Dictionary where Key: Equatable {
    func isEqualTo<ExcludedKeys: Sequence>(_ dictionary: Dictionary, excluding: ExcludedKeys = []) -> Bool where ExcludedKeys.Element == Key {
        // 转成Set优化contains查询效率,尤其是排除键数量较多时
        let excludedSet = Set(excluding)
        let left = filter { !excludedSet.contains($0.key) }
        let right = dictionary.filter { !excludedSet.contains($0.key) }
        return NSDictionary(dictionary: left).isEqual(to: right)
    }
}

改动说明

  1. 泛型Sequence约束:通过泛型ExcludedKeys并约束它遵循Sequence且元素为Key,这样所有Key的序列类型(包括Dictionary.Keys、Set<Key>、普通Array)都能直接传入,无需额外类型转换。
  2. 性能优化:将传入的序列转成Set<Key>,因为Set的contains操作是O(1)时间复杂度,而数组的contains是O(n),当需要排除的键较多时,这个优化能明显提升比较速度。

现在可以直接调用啦

// 不用再写Array(car.keys),直接传car.keys即可
foo.isEqualTo(bar, excluding: car.keys)

如果你的Swift版本在5.7及以上,还可以用更简洁的any Sequence<Key>写法,效果完全一致:

extension Dictionary where Key: Equatable {
    func isEqualTo(_ dictionary: Dictionary, excluding: any Sequence<Key> = []) -> Bool {
        let excludedSet = Set(excluding)
        let left = filter { !excludedSet.contains($0.key) }
        let right = dictionary.filter { !excludedSet.contains($0.key) }
        return NSDictionary(dictionary: left).isEqual(to: right)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:59:28