【问题标题】:How to create a collection of Identifiable objects similar to Set?如何创建类似于 Set 的 Identifiable 对象集合?
【发布时间】:2020-05-19 13:25:43
【问题描述】:

Set 非常适合避免重复、联合和其他操作。但是,对象不应该是Hashable,因为对象中的更改会导致Set 中的重复。

SwiftUI 中有一个List,它使用Identifiable 协议来管理集合,但面向视图。是否有以相同方式运作的集合?

例如,对于以下对象,我想管理一个集合:

struct Parcel: Identifiable, Hashable {
    let id: String
    var location: Int?
}

var item = Parcel(id: "123")
var list: Set<Parcel> = [item]

稍后,我改变项目的位置并更新列表:

item.location = 33435
list.update(with: item)

由于哈希值已更改,这会将重复项添加到列表中,但由于它具有相同的标识符,因此不打算这样做。有没有处理Identifiable 对象集合的好方法?

【问题讨论】:

  • 问我看到的难题。我会给你一个赞成票。
  • 我怀疑您需要扩展一个集合并根据给定的谓词手动检查元素。因此,假设您有一个Set&lt;Car&gt;,并且您添加了HondaHonda,通常该设置不允许这样做,但您可能需要告诉Set&lt;Car&gt;,第二个本田只有 3x 轮胎而不是 4。从表面上看,它看起来像复制品,但实际上并非如此。另一种选择是识别WHY 如果散列改变,它是否允许重复?扩展该功能并删除不需要的行为。
  • 似乎以标识符为键的字典是最好的本土方法,但希望有像 SwiftUI 的 List 这样的原生和优雅的东西。
  • 这是有道理的。字典是一种“集合”,每个条目只允许一个键。如果您的密钥保持不变,那么值是什么并不重要,它只会允许一个密钥。我有点困惑这怎么不优雅。字典似乎相当简单。
  • 为什么不为您的类型覆盖Hashable 的默认实现? func hash(into hasher: inout Hasher) { hasher.combine(id) }

标签: arrays swift uniqueidentifier


【解决方案1】:

仅使用 id 属性为您的类型实现 hash(into)(和 ==)

func hash(into hasher: inout Hasher) { 
    hasher.combine(id) 
}

static func == (lhs: Parcel, rhs: Parcel) -> Bool {
    lhs.id == rhs.id
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-13
    • 1970-01-01
    • 2022-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-12
    相关资源
    最近更新 更多