Sort custom objects by property in Swift

· 1 min read
Sort custom objects by property in Swift

Many of us have met the situation that we have an array/list of custom objects, and we want them can be sorted in a specific order. For example, we are have a group of people, and we want to sort the whole array by the person's age.

struct Person {
  let firstName: String
  let lastName: String
  let age: Int
}

var people = [Person(firstName: "John", lastName: "Smith", age: 25),
              Person(firstName: "Jane", lastName: "Doe", age: 35),
              Person(firstName: "Bob", lastName: "Jones", age: 20)]

let sortedPeople = people.sorted { $0.age < $1.age }
// output
[__lldb_expr_3.Person(firstName: "Bob", lastName: "Jones", age: 20), __lldb_expr_3.Person(firstName: "John", lastName: "Smith", age: 25), __lldb_expr_3.Person(firstName: "Jane", lastName: "Doe", age: 35)]

Sort objects by a custom property

Note that we can sort the Person struct above easily due to its properties are all in prime type. What about custom property, see the example:

let people = [Person(firstName: "John", lastName: "Smith", age: 25),
              Person(firstName: "Jane", lastName: "Doe", age: 35),
              Person(firstName: "Bob", lastName: "Jones", age: 20)]

let sortedPeople = people.sorted { $0.age < $1.age }
print(sortedPeople)

let companies = [
  Company(name: "A", ceo: people[0]),
  Company(name: "B", ceo: people[1]),
  Company(name: "C", ceo: people[2])
]
let sortedCompanies = companies.sorted { $0.ceo < $1.ceo }
print(sortedCompanies)

If we run the above code we will get the error:

Referencing operator function '<' on 'Comparable' requires that 'Person' conform to 'Comparable'

The compiler indicated that we need our Person to conform the Comparable protocol (For more details on the Equatable and Comparable in Swift):

struct Person: Comparable {
  
  let firstName: String
  let lastName: String
  let age: Int
  
  static func < (lhs: Person, rhs: Person) -> Bool {
    lhs.age < rhs.age
  }
}

Now if we rerun the code, we will get a sorted company array based on the ceo property:

[__lldb_expr_7.Company(name: "C", ceo: __lldb_expr_7.Person(firstName: "Bob", lastName: "Jones", age: 20)),

__lldb_expr_7.Company(name: "A", ceo: __lldb_expr_7.Person(firstName: "John", lastName: "Smith", age: 25)),

__lldb_expr_7.Company(name: "B", ceo: __lldb_expr_7.Person(firstName: "Jane", lastName: "Doe", age: 35))]