Equatable and Comparable in Swift

· 2 min read
Equatable and Comparable in Swift

It is quite common that we are required to compare two custom objects in Swift, luckily Swift has provided some built-in protocol allows us to do this in a "swift" way.

Equatable

In Swift, Equatable is a protocol that allows us to determine whether two reference objects are equal. To conform to this protocol, a type must implement the == operator, which is going to implement which properties can be compared, let us have a look at the following example:

class Car {
    let make: String
    let model: String
    let year: String?

    init(_ make: String, _ model: String, _ year: String? = nil) {
        self.make = make
        self.model = model
        self.year = year
    }
}

To check two Car objects (or instances) are equal or not, we can let it comfort to Equatable protocol:

extension Car: Equatable {
    static func == (lhs: Car, rhs: Car) -> Bool {
        return
            lhs.make == rhs.make &&
            lhs.model == rhs.model &&
            lhs.year == rhs.year
    }
}

Then we can check whether tow cars are same in this way:

let car1 = Car("Lexus", "NX200T", "2010")
let car2 = Car("Lexus", "NX200T", "2010")
print(car1 == car2)	// true

Comparable

With Equatable, we can check whether two objects are same, but we don't know which one is "bigger" or "smaller".  For example, we might need to sort an array with custom objects in Swift with given values. Luckily, similar to Equatable we have Comparable for such scenarios. Let us continue the above example:

extension Car: Comparable {
    static func < (lhs: Car, rhs: Car) -> Bool {
        if let _lYear = lhs.year, let _rYear = rhs.year {
            return _lYear < _rYear
        } else {
            return lhs.make < rhs.make
        }
    }
    
    static func == (lhs: Car, rhs: Car) -> Bool {
        lhs.make == rhs.make && lhs.model == rhs.model && lhs.year == rhs.year
    }
}

We can just need to implement < operator, as the rest others can be derived from that. For instance >.

Unlike Equatable, the compiler does not automatically conforms to Comparable protocol.

Summary

In Swift, Comparable and Equatable are two protocols that define a set of methods that a class/struct/enum must implement in order to be able to be compared or tested for equality.

An object that conforms to the Comparable protocol must implement the <  operator, which are used to compare two values of the same type. By conforming to Comparable protocol, we are able to do sort on in a collection of custom objects.

The Equatable protocol is similar, but it only requires that the == operator be implemented which requires two values of the same type to be tested for equality.

In practice, if you want to compare and sort two values of a custom type, you would implement both the Comparable and Equatable protocols. This allows the values to be compared using the < and == operators, as well as other comparison operators that may be defined for the type.