In Swift, a Hashable is a protocol that provides a hashValue
to our object. The hashValue
is used to compare two instances.
To use the hashValue
, we first have to conform (associate) the type (struct, class, etc) to Hashable property. For example,
struct Employee: Hashable {
...
}
Here, we have conformed the Employee struct to the Hashable
protocol.
Now when we create instances of Employee, the protocol will provide hash values to the instances.
Example: Swift Hashable Protocol
struct Employee: Hashable {
var name: String
}
let object1 = Employee(name: "Sabby")
let object2 = Employee(name: "Smith")
// print hash values
print(object1.hashValue)
print(object2.hashValue)
Output
754256748862435114 -6408043519205941253
Here, object1.hashValue
and object2.hashValue
returns hash values for instances object1 and object2 respectively.
Note: A hash value is a long integer that varies based on the system you are using, so you might get different values for the same code.
Compare Instances using Hashable Protocol
// conform Employee to Hashable
struct Employee: Hashable {
var name: String
var salary: Int
}
// initialize two objects with different property values
let obj1 = Employee(name: "Sabby", salary: 40000)
let obj2 = Employee(name: "Cathy", salary: 30000)
print("Different hash value: ")
print(obj1.hashValue)
print(obj2.hashValue)
// initialize two objects with same property values
let obj3 = Employee(name: "Lanny", salary: 50000)
let obj4 = Employee(name: "Lanny", salary: 50000)
print("\nSame hash value: ")
print(obj3.hashValue)
print(obj4.hashValue)
Output
Different hash value: 3934953678767833906 4997634560615333199 Same hash value: 1588129438168529318 1588129438168529318
In the above example, we have created a struct named Employee that conforms to the Hashable
protocol.
We have created two objects obj1 and obj2.
let obj1 = Employee(name: "Sabby", salary: 40000)
let obj2 = Employee(name: "Cathy", salary: 30000)
Here, both instances have different values for properties name and salary. That's why hash values for obj1 and obj2 are different.
Similarly, we have created two more objects.
let obj3 = Employee(name: "Lanny", salary: 50000)
let obj4 = Employee(name: "Lanny", salary: 50000)
This time properties values for obj3 and obj4 are the same, so we get the same hash values for the instances.
Hash Function and Combine
In the above example, we have compared all the properties of the struct.
However, sometimes we may want to compare selective properties of the type. In this case, we may use the hash function inside the type. For example,
func hash(into hasher: inout Hasher) {
hasher.combine(name)
}
Here, the hash()
function uses hasher.combine()
to specify the property that we want to compare.
Use of Hash Function
struct Employee: Hashable {
var name: String
var salary: Int
// create a hash() function to only compare age property
func hash(into hasher: inout Hasher) {
hasher.combine(salary)
}
}
// initialize two objects with different values for salary property
let obj1 = Employee(name: "Sabby", salary: 349879)
let obj2 = Employee(name: "Sabby", salary: 422532)
print(obj1.hashValue)
print(obj2.hashValue)
Output
3932232896576771782 743881919875172951
In the above example, we have used the hash()
function to compare two instances on the basis of the salary property
func hash(into hasher: inout Hasher) {
hasher.combine(salary)
}
Here, the salary of ob1 and obj2 are different, so we get different hash values.
If we have used the name property inside the hash()
function, we will get the same hash value. This is because name of both objects are the same.
func hash(into hasher: inout Hasher) {
hasher.combine(age)
}
// Output:
// 976332112043722041
// 976332112043722041