In the last article, we introduced protocol Equatable. Today protocol Comparable will be covered. The Integer type is inherently comparable like 5 < 7. How about our self-defined types? How to bring order to superheroes we defined in Part 1 ? Is superman > batman possible in Swift world?

We will follow our procedure to show Comparable’s source code first. The following codes are from Comparable. Swift

public protocol Comparable : Equatable {
    static func < (lhs: Self, rhs: Self) -> Bool
    static func <= (lhs: Self, rhs: Self) -> Bool
    static func >= (lhs: Self, rhs: Self) -> Bool
    static func > (lhs: Self, rhs: Self) -> Bool
}
Copy the code

Four relational operators are defined in this protocol, but we only need to implement < in conformance to Comparable. The other three operators has been given default implementations.

public func > <T : Comparable>(lhs: T, rhs: T) -> Bool {
  return rhs < lhs
}
Copy the code
public func <= <T : Comparable>(lhs: T, rhs: T) -> Bool { return ! (rhs < lhs) }Copy the code
public func >= <T : Comparable>(lhs: T, rhs: T) -> Bool { return ! (lhs < rhs) }Copy the code

Let’s enhance our Superhero type to give each hero a power value.

struct Superhero {
    let firstName: String
    let lastName: String
    let age: Int
    var power: Int
}
Copy the code

And update Superman and Batman.

let superman = Superhero(firstName: "Clark", lastName: "Kent", age: 35, power: 100)
let batman = Superhero(firstName: "Bruce", lastName: "Wayne", age: 32, power: 90)
Copy the code

Ok, maybe you don’t agree with me and Batman is top one on your list. Never mind change the value as you wish.

In the world built by me in Swift, superheroes are ordered by their power value.

extension Superhero: Comparable {

    static func < (lhs: Superhero, rhs: Superhero) -> Bool {
        return lhs.power < rhs.power
    }

    static func == (lhs: Superhero, rhs: Superhero) -> Bool {
        return lhs.firstName == rhs.firstName &&
            lhs.lastName == rhs.lastName &&
            lhs.age == rhs.age
    }
}
Copy the code

As we mentioned, Comparable extends Equatable, so we need to implement == at the same time.

Then let’s start Before & After comparison.

Before:

let superheroes = [superman, batman]
Copy the code
let isSupermanTopOne = superman.power > batman.power

superheroes.sorted(by: {$0.power < $1.power })
Copy the code

After:

let isSupermanTopOne = superman.power > batman.power

superheroes.sorted()
Copy the code

In the next article, we will introduce protocol Hashable.