我正在为项目列表实现标记功能。我正在尝试实现一个计算属性,计算项目列表中的标记集作为每个项目的不同标记集的联合,如:
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
}
}
如何仅访问标签描述以获得正确的结果?由于
这可以使用reduce
和union
函数来完成
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
}
}