🎓 A1Learner
🔍
0 of 36 lessons completed

Swift Sorting in Depth

Sorting in depth is ordering a collection with a rule written as a closure. The closure compares two elements and answers whether the first one belongs before the second one.

Numbers from largest to smallest

The greater than operator works as the closure, so larger numbers belong first. The first print shows the new order, and the second print shows the original array untouched.

let numbers = [3, 7, 1, 9]
let highToLow = numbers.sorted(by: >)
print(highToLow)
print(numbers)

Words by length, shorter first

The closure compares the count of each word. The shortest word belongs first in the new array.

let words = ["horse", "cat", "elephant", "ox"]
let byLength = words.sorted(by: { $0.count < $1.count })
print(byLength)

Structs by one property

Each player holds a name and a score. The closure compares scores, so the highest score belongs first in the ranked array.

struct Player {
    let name: String
    let score: Int
}
let players = [Player(name: "Ana", score: 80), Player(name: "Ben", score: 95), Player(name: "Cleo", score: 70)]
let ranked = players.sorted(by: { $0.score > $1.score })
for player in ranked {
    print("\(player.name) \(player.score)")
}

A tie broken by a second check

Two players share the top score of 90, so the closure falls back to comparing names. The sort call changes the players array itself, and Ana prints before Ben.

struct Player {
    let name: String
    let score: Int
}
var players = [Player(name: "Ben", score: 90), Player(name: "Ana", score: 90), Player(name: "Cleo", score: 80)]
players.sort(by: {
    if $0.score != $1.score {
        return $0.score > $1.score
    }
    return $0.name < $1.name
})
for player in players {
    print("\(player.name) \(player.score)")
}

Example

struct Item {
    let name: String
    let price: Int
}
let items = [Item(name: "Pen", price: 5), Item(name: "Book", price: 5), Item(name: "Bag", price: 12)]
let cheapFirst = items.sorted(by: {
    if $0.price != $1.price {
        return $0.price < $1.price
    }
    return $0.name < $1.name
})
for item in cheapFirst {
    print("\(item.name) \(item.price)")
}
for item in items {
    print("Original \(item.name)")
}

Key points

  • Sorted with a closure returns a new array in the order the closure decides.
  • Sort with a closure changes the array it is called on.
  • Passing the greater than operator as the closure sorts numbers from largest to smallest.
  • A closure can compare one property of each element, such as count or score.
  • When two elements tie on the first check, the closure can compare a second property to break the tie.

In this example, the closure compares prices first, so the two items priced at 5 belong before the item priced at 12. Pen and Book tie on price, so the closure compares names and Book belongs before Pen. The sorted call returns a new array, and the last loop proves the original items still sit in their starting order.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

A program needs the ordered values in a new array while the original array keeps its order. Which call fits?