ios - 如果 Set 包含它,则更改数组内所有元素的变量

标签 ios arrays swift set

我知道这是一个愚蠢的问题,但我不知道哪个是更高效的解决方案。我有一个数组 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 中的每一项, 然后设置 isSelectedtrue对于您的 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/

相关文章:

ios - Swift CGAffineTransformScale 到一个比例,而不是一个比例

javascript - react native TypeError : Attempted to assign to readonly property

PHP preg_match 查找相关单词

c - 为什么我在用 C 填充字符数组时会得到额外的字符?

快速刷新控件 fatal error : unexpectedly found nil while unwrapping an Optional value

ios - 从一个 View Controller 切换到另一个 View Controller 的推荐方法是什么?

iOS; NSAutoreleasePool 过时了吗?

java - 从 jsp 检索更新的数组列表到 struts2 中的 Action 类

ios - 如何实现像 YouTube 这样的视频 Controller 旋转到横向

ios - iAd 引起约束冲突