如何在Swift中使一组对象中的属性符合哈希协议?



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

item1 - [tag1, tag2]

item2 - [tag1, tag3]

输出比;[标签1,标签2,tag3]

问题在于Tag类需要是可哈希的,并且每个标记实例都有一个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>()){ $0.union($1) }
}

注意,对于Hashable,您需要为TTDTag实现hash(into:)

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

你应该用小写字母开始属性名,并使它们具有描述性,例如你可以将TTDTagDesc更改为tagDescription

hashValue已被弃用(您应该已经收到警告)。你应该重写hash(into:),在那里使用你的TTDTagDesc属性。

同样,您应该实现id以返回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
}
}

相关内容

  • 没有找到相关文章

最新更新