2

Can someone please visualize the process of sorting?

let numbers = [0,2,1]
let sortedNumbers = numbers.sorted { $0 > $1 }

If I were to sort these 3 numbers in descending order in real life, it would result in this: scrSh1, but Swift makes it complicated: scrSh2.

How can there be 4 returns and why is the last one 'false'? How are the arguments $0 and $1 changing their positions?

LinusGeffarth
  • 27,197
  • 29
  • 120
  • 174
PigeonPO
  • 74
  • 8
  • 1
    It's about the sort algorithm used. You compare two elements $0 and $1. And you move them according to the result. You should be able to add a log to show $0 and $1 each time. – Larme Mar 29 '17 at 15:20
  • @Larme Yeah, i tried just to print each result, but i think it's not possible. – PigeonPO Mar 29 '17 at 15:23
  • @PigeonPO I have an answer here which breaks down all the various closure syntactic sugars: http://stackoverflow.com/a/40390414/3141234 – Alexander Mar 29 '17 at 15:28

5 Answers5

3

Run it like this in a playground, and you will see how it works in more detail:

let numbers = [0,2,1]
let sortedNumbers = numbers.sorted {
    print("0: \($0), 1: \($1), returning \($0 > $1)")

    return $0 > $1
}

$0 is simply the first argument, and $1 is the second. The output with your numbers array is:

0: 2, 1: 0, returning true
0: 1, 1: 0, returning true
0: 1, 1: 2, returning false
David S.
  • 6,567
  • 1
  • 25
  • 45
1

It is a syntactic simplification, it is equivalent to:

numbers.sorted {(a, b) -> Bool in
        return a > b
    }

In fact $0 is the first parameter of the closure, $1 is the second one...

Edit: The fact that it is called 4 times, it's just because of the sort algorithm used. And you should not take care of it.

Zaphod
  • 6,758
  • 3
  • 40
  • 60
1

It's shortly but comprehensively described in the documentation:

let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]

...

reversedNames = names.sorted(by: { s1, s2 in s1 > s2 } )

Shorthand Argument Names

Swift automatically provides shorthand argument names to inline closures, which can be used to refer to the values of the closure’s arguments by the names $0, $1, $2, and so on.

If you use these shorthand argument names within your closure expression, you can omit the closure’s argument list from its definition, and the number and type of the shorthand argument names will be inferred from the expected function type. The in keyword can also be omitted, because the closure expression is made up entirely of its body:

reversedNames = names.sorted(by: { $0 > $1 } ) 

Here, $0 and $1 refer to the closure’s first and second String arguments.

vadian
  • 274,689
  • 30
  • 353
  • 361
0

The sorted function takes a closure which defines the ordering of any two elements. The sorting algorithm does a series of comparisons between items, and uses the closure to determine the ordering amongst them.

Here's an example which prints out all the comparisons done in the sorting of an example array of numbers:

let numbers = [0, 9, 1, 8, 2, 7, 3, 6, 4, 5]
let sorted = numbers.sorted { (a: Int, b: Int) -> Bool in
    let result = a < b
    print("\(a) is \(result ? "" : "not") before \(b)")
    return result
}

print(sorted)

$0 and $1 are implicit closure parameters. They're names implicitly given to the parameters of a closure. They're often used in cases where the names given to parameters of a closure are rather arbitrary, such as in this case.

In your example, the closure behaves as if it was like so:

let numbers = [0,2,1]
let sortedNumbers = numbers.sorted { leftElement, rightElement in
    return leftElement > rightElement
}

As you can see leftElement and rightElement don't add much information to the code, which is why it's preferred to use implicit closure parameters in a case like this.

Alexander
  • 59,041
  • 12
  • 98
  • 151
0

The "(4 times)" means your closure ({ $0 > $1 }) is getting invoked 4 times by the sorted function.

I don't know what the false means, but presumably it's the last return value from your closure, which depends entirely on the internal sorting algorithm used by sorted (which you can visualize e.g. with David Shaw's method). I.e. $0 and $1 are not "changing their positions".

Emil Laine
  • 41,598
  • 9
  • 101
  • 157