Came across this new “sort(by:)” method in my study book, without any reasonable explanation for how and why it works, with this for a code example:
var numbers = [1, 2, 5, 3, 7, 4, 6, 9, 8]
let sortClosure = { (a: Int, b: Int) -> Bool in
return a < b
}
numbers.sort(by: sortClosure)
print(numbers)
With my own research I found that if a (first element of the array) needs to be before b (second element of the array), the closure returns true and sorts the array that way.
But my compiler says return a < b == false
and return a > b == true
and I can't understand why, because how can 2 be less than 1?
Please, help me to understand what's wrong with my compiler or what I can't understand it's working from the sort(by:)
method?
There are various sort algorithm: Bubble Sort, Quicksort, merge sort, etc.
They have they pros/cons, mostly about : memory use, complexity, etc. In a nutshell: Will it create another full array or more in memory while sorting? Will it takes a lot of time if the array if big? etc.
In this other StackOverflow question, you might see which algorithm seems to be used, and it seems that the algorithm changed in the past. And tomorrow, the algorithm might change or even adapt (like: if there are less than 1k elements, do sort logic 1, but if there are more, do sort logic 2 because it's less expensive on memory and you have not a lot of RAM currently, etc.)
But as you want to use the high level method sort(by:)
, and not implement yourself the algorithm, do not focus on it.
Just focus on what to do in the closure which is quite simple:
You can print the value if you want:
let returnValue = a < b
print("Comparing \(a) vs \(b) and returning: \(returnValue)")
return returnValue
In your simple case, you are comparing the raw value which are Int
.
So the full lines of the previous explanation are:
let valueFromAToCompare = a
let valueFromBToCompare = b
return valueFromAToCompare < valueFromBToCompare
Which can obviously be simplified as return a < b
.
If we had structs like that in our array, and you want to sort according to its numbers:
struct MyStruct {
let number: Int
let subNumber: String
}
The closure would be:
let valueFromAToCompare = a.number
let valueFromBToCompare = b.number
return valueFromAToCompare < valueFromBToCompare
Which can be simplified into: return a.number < b.number
.
But as you can guess, there can be later more complex sort logic: compare the numbers, but if the number
s are equals, then compare the subNumber
, hence the closure which can let you put your whole logic:
if a.number == b.number {
return a.subNumber < b.subNumber
} else {
return a.number < b.number
}
Of course, it can simplified or written differently, but that's to make the example more comprehensible.