Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift: Can someone explain this syntax `numbers.sort { $0 > $1 }` for me?

Tags:

swift

First of all, this question is not about "what does $0 mean". I learnt in swift document that $0 is like index.

My question is "How numbers.sort { $0 > $1 } can be used to implement a sort function". I searched for this syntax numbers.sort { $0 > $1 } in some other websites, for example this one. It is apparently not the current version. So I still can't understand what the meaning of it.

print(numbers) //[20, 19, 1, 12]
let sortedNumbers = numbers.sort { $0 > $1 }
print(sortedNumbers) //[20, 19, 12, 1]

Can someone explain this simple piece of code above for me? Like how this simple code $0 > $1 implement the sort function, sorting the numbers from big to small.

I know some about index, and this $0 looks like index, but it only has $0 and $1 two indices. So how can it be used into 4 numbers? According to my knowledge in C++ before, I can't understand the principle in this.

Please make your answer as specific as possible. Thank you!

----------------- Below is edited extra part -------------------

I don't know whether stackoverflow would allow me to edit my question like this, but this extra part is too long, so I can't add it in the comment. @pbodsk @Paul Richter

So the sort() syntax in swift uses quick sort to deal with sort function?

Actually my question is more about "what is the operating principle of sort{$0 > $1}". I know what you mean above, and I think it's similar with what swift 2.1 document says, but your answer is not what I really want to know. Sorry, my English expression is not very good. Let me try another way.

When I learnt C++ before, there are always some documents to explain what a function's operating principle is or how this function (like sort() here) operate in background. Sort() here needs to compare first and second interchange. In C++, it's like

if numbers[1] < numbers[2]{ //just consider this pseudocode
    int k;
    k = numbers[1];
    numbers[1] = numbers[2];
    numbers[2] = k;
}

We can see this process is obvious. In swift, it's like

numbers.sort({(val1: Int, val2: Int) -> Bool in
   return val1 > val2
})

Where is it compared? And how is it interchanged? Does return val1 > val2 automatically compare and interchange these two values and return them? Just this one syntax implement these all 3 processes? How? This is what I really want to know. Sorry again for my poor English expression.

like image 860
JW.ZG Avatar asked Jan 14 '16 06:01

JW.ZG


People also ask

What is $0 and $1 in Swift?

$0 and $1 are closure's first and second Shorthand Argument Names (SAN for short) or implicit parameter names, if you like. The shorthand argument names are automatically provided by Swift. The first argument is referenced by $0 , the second argument is referenced by $1 , the third one by $2 , and so on.

What is use of $0 in Swift?

$0 is a shortcut to mean "first argument" in a closure.

How do I sort a value in Swift?

In Swift, we can also sort arrays in ascending and descending order. To sort the array we use the sort() function. This function is used to sort the elements of the array in a specified order either in ascending order or in descending order.

How do I sort integers in Swift?

To sort an integer array in increasing order in Swift, call sort() method on this array. sort() method sorts this array in place, and by default, in ascending order.


2 Answers

@the_UB and @moonvader are both right, but I just thought that I would extend the example from @moonvader a bit, just to show you how we end up with $0 > $1

If you look at the example in "The Swift Programming Language" about Closure Expressions you can see that to sort an array you call the sort method which can then take a function as a parameter.

This function must take two parameters and compare them, and then return a boolean.

So if we have this array:

let numbers = [4, 6, 8, 1, 3]

and this method

func sortBackwards(val1: Int, val2: Int) -> Bool {
   print("val1: \(val1) - val2: \(val2)" )
   return val1 > val2
}

We can sort the elements like so:

numbers.sort(sortBackwards) //gives us [8, 6, 4, 3, 1]

The sort method will use our sortBackwards method on each of the elements in the array and compare them.

Here's the output of the print

val1: 6 - val2: 4
val1: 8 - val2: 4
val1: 8 - val2: 6
val1: 1 - val2: 4
val1: 3 - val2: 1
val1: 3 - val2: 4

OK, let's reduce that.

Instead of defining a function, we can add that directly as a parameter to the sort method like so:

numbers.sort({(val1: Int, val2: Int) -> Bool in
   return val1 > val2
})

And we still end up with [8, 6, 4, 3, 1] (how fortunate!)

OK, the next thing we can do is what in "The Swift Programming Language" (the link above) is called "Infering Type From Context". As we call this method on an array of Ints, Swift can figure out that our val1 and val2 parameters must be Ints too, there's no need for us to tell it. So, lets remove the types. That leaves us with:

numbers.sort({val1, val2 in
   return val1 > val2
})

And still the same result.

OK, getting there. The next thing we can do is what in the book is called "Implicit Returns from Single-Expression Closures"

As our comparison can be done in one line there's no need for us to use return. So:

numbers.sort({val1, val2 in val1 > val2})

Still gives us [8, 6, 4, 3, 1]

Finally we're getting to what @moonvader used much much less words to explain :-) namely "Shorthand Argument Names"

As it says in the book:

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.

So, in our example, val1 can be replaced by $0 and val2 can be replaced by $1

Which gives us:

numbers.sort({$0 > $1})

And still we get [8, 6, 4, 3, 1]

We can then continue to use a "Trailing Closure", which means that if the last parameter of a function is a closure, we can add that parameter "outside" the function.

So we end up with:

numbers.sort{$0 > $1}

And the outcome is still [8, 6, 4, 3, 1]

Hope that helps to clarify things.

like image 119
pbodsk Avatar answered Sep 17 '22 12:09

pbodsk


Here is what all need to know: Sort and Sorted.

To be more specific, Sorting can be two type : Ascending and Descending.

Q - So to do sorting, what do we need?

A - We need two variables to hold two variable(I don't know if it is the correct word)

Hence in this case we have two variable $0 and $1. These both are shorthands to represent left and right variable. Both will help to sort.

">" will do descending.

"<" will do ascending.

like image 25
Bista Avatar answered Sep 20 '22 12:09

Bista