我知道这是一个愚蠢的问题,但我不知道哪个是更高效的解决方案。我有一个数组 ListItem
. ListItem
有一个 bool 值 isSelected
.我还有Set<ListItem>
.我想将该 bool 值更改为 true
如果数组有一个元素也在 Set 中。我怎样才能以最佳性能实现这一目标?
我的集合和数组:
var selectedItems = Set<ListItem>()
var array: [ListItem] = []
列表项:
class ListItem: Codable ,Equatable, Hashable {
let wrapperType: String
let kind: String?
let trackId: Int?
let artistId: Int?
let collectionId: Int?
let artistName, collectionName, trackName: String?
let trackViewUrl: String?
let artworkUrl30, artworkUrl60,artworkUrl100: String?
let releaseDate: String?
let primaryGenreName: String?
var isSelected: Bool = false
enum CodingKeys: String, CodingKey {
case wrapperType, kind
case artistId
case collectionId
case trackId
case artistName, collectionName, trackName
case trackViewUrl
case artworkUrl30, artworkUrl60, artworkUrl100, releaseDate, primaryGenreName
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
wrapperType = try container.decode(String.self, forKey: .wrapperType)
print(wrapperType)
kind = try container.decodeIfPresent(String.self, forKey: .kind)
trackId = try container.decodeIfPresent(Int.self, forKey: .trackId)
collectionId = try container.decodeIfPresent(Int.self, forKey: .collectionId)
artistId = try container.decodeIfPresent(Int.self, forKey: .artistId)
artistName = try container.decodeIfPresent(String.self, forKey: .artistName)
collectionName = try container.decodeIfPresent(String.self, forKey: .collectionName)
trackName = try container.decodeIfPresent(String.self, forKey: .trackName)
trackViewUrl = try container.decodeIfPresent(String.self, forKey: .trackViewUrl)
artworkUrl30 = try container.decodeIfPresent(String.self, forKey: .artworkUrl30)
artworkUrl100 = try container.decodeIfPresent(String.self, forKey: .artworkUrl100)
artworkUrl60 = try container.decodeIfPresent(String.self, forKey: .artworkUrl60)
releaseDate = try container.decodeIfPresent(String.self, forKey: .releaseDate)
primaryGenreName = try container.decodeIfPresent(String.self, forKey: .primaryGenreName)
}
static func ==(lhs: ListItem, rhs: ListItem) -> Bool {
return lhs.trackName == rhs.trackName
}
func hash(into hasher: inout Hasher) {
if trackId != nil {
hasher.combine(trackName)
} else if collectionId != nil {
//AudioBooks Doesn't have TrackId
hasher.combine(collectionId)
} else {
print("Both TrackId && Collection Id is null")
}
}
}
最佳答案
因为这些都是引用类型,如果保证任意唯一ListItem
只有一个实例, 只需设置 isSelected
就足够了至 false
对于您的 array
中的每一项, 然后设置 isSelected
至 true
对于您的 selectedItems
中的每一项.
array.forEach { $0.isSelected = false }
selectedItems.forEach { $0.isSelected = true }
如果一个项目可以有多个实例,您将不得不在 array
中迭代这些项目。并检查 Set
contains
他们。还好,contains
对于 Set
是 O(1) :
array.forEach { $0.isSelected = selectedItems.contains($0) }
注意:重要的是 hashValue
等于 ListItem
s 是相等的,否则这一切都会崩溃。你的hash(into:)
函数当前使用的字段多于您的 ==
函数,因此可以生成不同的 hashValue
等于ListItem
秒。修复此问题以确保正确的 hashValue
生成。
关于ios - 如果 Set 包含它,则更改数组内所有元素的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56921851/