Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift set equatable sometimes true sometimes false

I have a struct conforming to Hashable. This model is put in a Set. Randomly when I check if the set contains the model it returns true/false. Why is this?

enum Feature: String {
    case a
    case b
}

struct FeatureState: Hashable {
    let feature: Feature
    let isEnabled: Bool
}

extension FeatureState: Equatable {

    static func == (lhs: FeatureState, rhs: FeatureState) -> Bool {
        lhs.feature == rhs.feature
    }
}

let fs1 = FeatureState(feature: .a, isEnabled: false)
let fs2 = FeatureState(feature: .a, isEnabled: true)

featureStates.insert(fs1)
print(featureStates.contains(fs2)) // sometimes true, sometimes false
like image 415
Peter Warbo Avatar asked Aug 04 '26 09:08

Peter Warbo


1 Answers

Set.contains uses hashes to check whether an element is already part of the Set or not and only uses the == operator if the hash values of two elements are the same. Because of this, you need to provide your own hash(into:) implementation to make the hash value only dependant on feature, but not isEnabled.

struct FeatureState {
    let feature: Feature
    let isEnabled: Bool
}

extension FeatureState: Hashable {
    static func == (lhs: FeatureState, rhs: FeatureState) -> Bool {
        lhs.feature == rhs.feature
    }

    func hash(into hasher: inout Hasher) {
        hasher.combine(feature)
    }
}
like image 102
Dávid Pásztor Avatar answered Aug 06 '26 23:08

Dávid Pásztor