一组对象中的 属性 怎么可能符合 Swift 中的 Hashable 协议?

How is possible to a property in a Set of objects conform to Hashable protocol in Swift?

我正在为项目列表实现标签功能。我正在尝试实现一个计算的 属性 计算项目列表中的标签集作为每个项目的不同标签集的联合,例如:

item1 - [tag1, tag2]

item2 - [tag1, tag3]

输出 > [tag1, tag2, tag3]

问题是标签 class 需要是可散列的,并且在标签的每个实例中都给出一个 UID,即使是具有相同描述的标签。因此,当我循环所有项目标签列表以创建整个列表的标签集时,结果是错误的,如:

输出 > [tag1, tag1, tag2, tag3]

代码如下:

class TTDItem: Identifiable {
    
    var id: UUID = UUID()
    var itemDesc: String
    var itemTags: Set<TTDTag>
    
    init(itemDesc: String, itemTags: Set<TTDTag>) {
        self.itemDesc = itemDesc
        self.itemTags = itemTags
    }
}

class TTDTag: Identifiable, Hashable {
    
    var TTDTagDesc: String
    var hashValue: Int {
        return id.hashValue
    }
    
    init(TTDTagDesc: String){
        self.TTDTagDesc = TTDTagDesc
    }
    
    static func ==(lhs: TTDTag, rhs: TTDTag) -> Bool {
        return lhs.id == rhs.id
    }
}

class TTDItemList {
    var itemList: [TTDItem]
    init(itemList: [TTDItem]) {
        self.itemList = itemList
    }
    //(...)
    // implement computed property taglist
    func itemTagsList()-> Set<TTDTag> {
        var tagSet = Set<TTDTag>()
        for item in self.itemList {
            tagSet = tagSet.union(item.itemTags)
        }
        return tagSet
    }
}

如何才能只访问标签描述以获得正确的结果?谢谢

这可以使用 reduceunion 函数来完成

func itemTagsList()-> Set<TTDTag> {
    itemList.map(\.itemTags).reduce(Set<TTDTag>()){ [=10=].union() }
}

请注意,对于 Hashable,您需要为 TTDTag

实施 hash(into:)
func hash(into hasher: inout Hasher) {
    hasher.combine(TTDTagDesc)
} 

您应该 属性 名称以小写字母开头并使它们具有描述性,这样也许您可以将 TTDTagDesc 更改为 tagDescription

hashValue 已弃用(您应该已经收到警告)。您应该覆盖 hash(into:) 并在那里使用您的 TTDTagDesc 属性。

此外,您应该将 id 实现为 return TTDTagDesc,因为这是 识别 标签的方式。

class TTDTag: Identifiable, Hashable {
    
    var TTDTagDesc: String

    // Note here
    func hash(into hasher: inout Hasher) {
        hasher.combine(TTDTagDesc)
    }
    
    // and here
    var id: String { TTDTagDesc }
    
    init(TTDTagDesc: String){
        self.TTDTagDesc = TTDTagDesc
    }
    
    static func ==(lhs: TTDTag, rhs: TTDTag) -> Bool {
        return lhs.id == rhs.id
    }
}