0

Consider this struct

struct Node : Hashable {
 let value : Int
 let i : Int
 let j : Int

 init(withValue val : Int, position : (Int,Int)){
    value = val
    self.i = position.0
    self.j = position.1
 }

 var hashValue: Int {
    return "\(value),\(i),\(j)".hashValue
 }
}

My == operator

func ==(left: Node, right: Node) -> Bool {
    return left.hashValue == right.hashValue
}

When I create 2 nodes :

let node1 = Node(withValue: 1260, position: (8,694))
let node2 = Node(withValue: 33, position: (257,286))

And compare them :

   node1 == node2   //true ???

Why is the hashValue function not working as expected?

Should it be implemented in some different way?

Counter question : If yes, what is the right way to calculate hashValue for this kind of object?

More info

When I debugged this :

(lldb) po node1.hashValue
4799450060528192039

(lldb) po node2.hashValue
4799450060528192039
prad
  • 1,086
  • 1
  • 11
  • 19

1 Answers1

3

Equal hash values do not guarantee equal original values. The whole concept of hash collisions exists just for this reason:

In computer science, a collision or clash is a situation that occurs when two distinct pieces of data have the same hash value...

Collisions are unavoidable whenever members of a very large set (such as all possible person names, or all possible computer files) are mapped to a relatively short bit string.

It means that this implementation of == operator is wrong:

func ==(left: Node, right: Node) -> Bool {
    return left.hashValue == right.hashValue
}

Instead it should be:

func ==(left: Node, right: Node) -> Bool {
   return left.value == right.value
       && left.i == right.i
       && left.j == right.j
}
Community
  • 1
  • 1
0x416e746f6e
  • 9,872
  • 5
  • 40
  • 68