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

Swift中存储S1的Set如何以O(1)复杂度判断是否包含S2实例

解决方案

Swift 原生的 Set 是强类型泛型集合,Set<S1> 的默认 contains 方法只能接受 S1 类型参数,直接传入 S2 实例会编译报错。可以通过以下方案实现需求,全程保持 O(1) 时间复杂度:


方案1:扩展 Set 重载 contains 方法(最简便)

因为 S1 的相等判断、哈希计算都只依赖 data 字段,我们可以构造仅填充 data 字段的临时 S1 实例传入原生 contains 方法即可,临时实例的 otherData 可以随意填充,不会影响判断结果:

extension Set where Element == S1 {
    /// 支持传入 S2 实例查询是否存在
    func contains(_ s2: S2) -> Bool {
        // 构造临时占位 S1,otherData 随意填写,不影响判等和哈希结果
        let dummyS1 = S1(data: s2.data, otherData: "")
        return contains(dummyS1)
    }
}

调用方式完全符合预期:

let obj: S2 = ...
set.contains(obj) // 直接调用,O(1) 复杂度

方案2:抽取公共协议减少重复代码(适合多相似类型场景)

如果后续还有更多类似 S1、S2 的类型,哈希和判等都依赖 data 字段,可以抽取公共协议统一实现,避免每个类型都写重复的判等、哈希逻辑:

// 定义公共协议,要求实现 data 字段
protocol DataHashable: Hashable {
    var data: String { get }
}

// 给协议添加默认的判等、哈希实现,统一仅依赖 data
extension DataHashable {
    static func == (lhs: Self, rhs: Self) -> Bool {
        lhs.data == rhs.data
    }
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(data)
    }
}

// S1、S2 遵守协议即可,无需单独写判等和哈希逻辑
struct S1: DataHashable {
    let data: String
    let otherData: String
}
struct S2: DataHashable {
    let data: String
    let otherData: Int
}

后续新增同规则类型只要遵守 DataHashable 协议即可,再配合方案1的 Set 扩展就能实现跨类型查询。


注意事项

  • 请确保 S1 的判等、哈希逻辑永远仅依赖 data 字段,若后续修改了 S1 的相关逻辑记得同步更新 Set 扩展的实现,避免出现判断错误。
  • 临时构造的 S1 占位实例开销极低,不会影响性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 17:42:02