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?