@matt's answer is excellent. Please keep it as the accepted answer. I'd like to expand on it a bit.
When you pass your function backward to sorted(), behind the scenes, in code that you don't see, it calls backward multiple times to compare two items. To expose this behavior, add a print statement to backward:
func backward(_ s1: String, _ s2: String) -> Bool { print("backward comparing \(s1) and \(s2)") return s1 > s2 }
Then when you run:
var reversedNames = names.sorted(by: backward)
you will see:
backward comparing Alex and Chris backward comparing Ewa and Alex backward comparing Ewa and Chris backward comparing Barry and Alex backward comparing Barry and Chris backward comparing Daniella and Alex backward comparing Daniella and Barry backward comparing Daniella and Chris backward comparing Daniella and Ewa
So even though we don't see the sorted() code, it is obviously calling backward multiple times to compare the items in order to sort them.
There are numerous sorting algorithms, but they all have one thing in common. It is necessary to compare the items two at a time in the process of sorting them.
Case Study: Insertion Sort
Let's look at a real sorting algorithm and how it uses the sorting function that you pass it.
Below is an implementation of an insertion sort which is a very simple algorithm. Imagine you are given five playing cards to sort.
- Place the cards on a table, and then pick up the first one in your left hand. The cards in your left hand are the sorted cards. Since you only have one, the cards in your left hand are sorted by default.
- Now pick up a second card with your right hand and insert it into the correct place in your left hand. In order to do this, you will have to compare the card in your right hand to the cards in your left hand to find the right insertion point. Since you have just two cards, you just have to compare them to decide if the new card goes before or after the first card.
- Continue this process of picking up a card and inserting it into the right location for each card on the table until you are holding all of the cards in your left hand.
- The cards in your left hand are now sorted.
Here is insertion sort:
// Sort array by building up the sorted result array, inserting the // items one at a time into the result array which is always sorted func insertionSort(array original: [String], by comesBefore: (String, String) -> Bool) -> [String] { // start the result array off with the first item from the // original var result = original.isEmpty ? [] : [original.first!] // For every other item in the original array, find out where // it goes and insert it there for item in original.dropFirst() { // Have we found the insertion point? var found = false // The current insertion point into the result array var newidx = 0 // Loop while we haven't found the insertion point for the // current item and we haven't reached the end of the result // array while !found && newidx < result.count { // call the passed-in function to decide if the new item comes // before the current item of the result array if comesBefore(item, result[newidx]) { // Great! The current item comes before result[newidx], // so we now know where to insert it found = true } else { // Item doesn't come before result[newidx], so let's move // on to the next index newidx += 1 } } // Having found the insertion point, insert item into the result // array result.insert(item, at: newidx) } // Return the result array which now contains all of the items // which have been sorted by inserting them into the correct spots return result }
Now, run it:
let reversedNames = insertionSort(array: names, by: backward)
backward comparing Alex and Chris backward comparing Ewa and Chris backward comparing Barry and Ewa backward comparing Barry and Chris backward comparing Barry and Alex backward comparing Daniella and Ewa backward comparing Daniella and Chris
print(reversedNames)
["Ewa", "Daniella", "Chris", "Barry", "Alex"]
So, you see that the function you pass to insertionSort() is used to decide the order of the items. As @matt said, by taking a function, the sort lets you decide what comes before means.
names.sorted(by: >)