What must you do to have set operations work on custom objects?

怎甘沉沦 提交于 2019-12-10 14:54:44

问题


I made a little playground to do some tests on Set operations with custom objects but they are still failing and I have no idea why.

class User: NSObject {
    let id: String
    init(id: String) {
        self.id = id
        super.init()
    }

    override var hashValue: Int {
        get {
            return id.hashValue
        }
    }

    override var description: String {
        get {
            return id
        }
    }
}


func ==(lhs: User, rhs: User) -> Bool {
    return lhs.hashValue == rhs.hashValue
}

Then, I made two sets of User objects:

let user1 = User(id: "zach")
let user2 = User(id: "john")
let user3 = User(id: "shane")


let user4 = User(id: "john")
let user5 = User(id: "shane")
let user6 = User(id: "anthony")

let userSet1 : Set<User> = [user1, user2, user3]
let userSet2 : Set<User> = [user4, user5, user6]

But when I do an operation like so:

let newSet = userSet1.subtract(userSet2)
print(newSet)

newSet is identical to userSet1 and none of the sets are modified.

What must I do to get these set operations to work?

id:zach -> 4799450060450308971
id:john -> 4799450060152454338
id:shane -> -4799450060637667915
id:john -> 4799450060152454338
id:shane -> -4799450060637667915
id:anthony -> 4799450059843449897
id:shane -> -4799450060637667915
id:anthony -> 4799450059843449897
id:john -> 4799450060152454338

回答1:


You do not get to make up your own idea of what to use as a hash value. The requirement for hashability is: the hash value of two objects must be the same if those two objects are equal.

You have provided a hash value algorithm but you have done nothing about making equatability of your User objects match it.

Here is a User object that is hashable in a set:

func ==(lhs:User, rhs:User) -> Bool {
    return lhs.id == rhs.id
}
class User: Hashable, CustomStringConvertible {
    let id: String
    init(id: String) {
        self.id = id
    }
    var hashValue: Int {
        return id.hashValue
    }
}

Observe that I have removed the complication of making this thing also an NSObject. Things are a bit different if you want to do that; you'll need to think about how NSObject works.



来源:https://stackoverflow.com/questions/33056955/what-must-you-do-to-have-set-operations-work-on-custom-objects

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!