Sorting an Array of Objects in Swift: From Simple to Complex

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

How to Sort an Array of Objects by Property in Swift: A Look Under the Hood



Hello, colleague! If you've ever written a Swift app that displays a list of users, products, or tasks, you've likely faced the need to sort that data. The question "How to sort an array of custom objects by property value?" is one of the most popular on Stack Overflow. And for good reason: at first glance, it seems simple, but dig a little deeper, and a whole world of possibilities opens up.



Today, we won't just give you a ready-made answer. We'll break down how sorting works under the hood in Swift, what mechanisms are involved, and how to write not just functional, but efficient and elegant code. Let's go!



What is Sorting an Array of Objects in Swift?



Imagine you have an array of User objects. Each user has a name, age, and rating. You need to display them on the screen, sorted by age (from youngest to oldest).



In Swift, this is done using the built-in methods sort() (sorts the array in place) and sorted() (returns a new sorted array). Both accept a closure that defines the order.



struct User {    let name: String    let age: Int    let rating: Double}

let users = [ User(name: "Anna", age: 25, rating: 4.5), User(name: "Boris", age: 30, rating: 3.8), User(name: "Vika", age: 22, rating: 4.9)]

// Sorting by age (ascending)let sortedByAge = users.sorted { $0.age < $1.age }print(sortedByAge.map { $0.name }) // ["Vika", "Anna", "Boris"]


That's it. But let's understand what's actually happening here.



How sort() Works Under the Hood: Algorithms and Closures



The sort() method in Swift uses a hybrid algorithm called TimSort (named after Tim Peters). It's an adaptive, stable sorting algorithm that combines merge sort and insertion sort. It's particularly efficient on partially sorted data — hello, news feeds and task lists!



The closure you pass is a sorting predicate: a function that takes two elements and returns true if the first should come before the second. Swift calls this closure repeatedly, comparing pairs of elements.



Important: if your objects conform to the Comparable protocol, you can skip the closure entirely:



struct User: Comparable {    let name: String    let age: Int        static func < (lhs: User, rhs: User) -> Bool {        return lhs.age < rhs.age    }}

let sortedUsers = users.sorted() // now it's simple


But what if you need to sort by different properties at runtime? This is where KeyPath comes to the rescue.



Sorting with KeyPath: Elegance and Flexibility



Starting with Swift 4, we have KeyPath. It's a type-safe way to refer to an object's property. Combining KeyPath with closures allows you to write a universal sorting function:



extension Array {    mutating func sort<T: Comparable>(by keyPath: KeyPath<Element, T>, ascending: Bool = true) {        sort { ascending ?            $0[keyPath: keyPath] < $1[keyPath: keyPath] :            $0[keyPath: keyPath] > $1[keyPath: keyPath]        }    }        func sorted<T: Comparable>(by keyPath: KeyPath<Element, T>, ascending: Bool = true) -> [Element] {        return sorted { ascending ?            $0[keyPath: keyPath] < $1[keyPath: keyPath] :            $0[keyPath: keyPath] > $1[keyPath: keyPath]        }    }}

// Usage:users.sort(by: \\.age) // by age (ascending)let sortedByRating = users.sorted(by: \\.rating, ascending: false) // by rating (descending)


Beautiful, isn't it? Type-safe

Blogs

Book Recommendations