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

后端 未结 4 2124
慢半拍i
慢半拍i 2020-12-09 00:01

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 >

4条回答
  •  粉色の甜心
    2020-12-09 00:38

    The process of sorting a list consists of repeatedly reordering its elements until nothing remains to be reordered. Now there are many sorting algorithms, but they all do this, in different ways. So then how are elements reordered? By comparing two given elements, and deciding which comes first, and swapping them if needed.

    We can separate the overall reordering and swapping parts from the comparison part, and write a sort function that will take care of all the repeated reordering stuff, and just require the caller to specify how to compare two elements. If the list consists of numbers, it's almost always the case that the way to compare them is to just take their value. But suppose the list consists of things a little more complicated, like cars. How do you compare two cars? Well, you could compare them by numerically comparing their top speed. Or their gas mileage. Or price.

    But the comparison doesn't have to be numerical. We could compare two cars by actually racing them. We could compare two cars by just saying if one is blue and the other isn't, the blue one is ordered first, and if neither or both are blue they are ordered as they already are.

    We could come up with all sorts of ways to compare two cars. And the sorting algorithm could then sort a list of cars, without knowing anything about cars, as long as we the caller just tell it how to compare cars - any two given cars. We just have to express that comparison as an expression that returns a boolean, where if it's true, the first car is ordered before the second one, and if it's false, the first car is ordered after the second one.

    Returning to numbers, that's what sort { $0 > $1 } means, in Swift's very concise syntax: "Sort, where if the first element is > the second one, order the first one before the second one."

    You asked how it can sort four numbers with only two indices. $0 and $1 are not bound to the four specific elements in the list [20, 19, 1, 12], they are bound to any two given numbers that need to be compared, because the sorting algorithm repeately needs to do this.

    There are a few things to note. First, the operator > has to be defined for the kinds of elements you are sorting. In the example the elements are numbers, and > is indeed defined. Second, the sort function specifies that the boolean true orders the first one before the second rather than the other way around, so the comparison function follows that specification. Third, the last evaluated expression is taken as the boolean value to be used. Having these two assumptions beforehand allows the comparison function to be written so concisely.

    So if we wanted to sort those cars by racing them, we could write it like this:

    cars.sort {
      winner_of_race_between($0, $1) == $0 
      // if the first car beats the second, it is sorted ahead
    }
    

    Or exclusive blueness:

    cars.sort { //not guaranteed to be valid Swift, just consider this pseudocode
      if(($0.color != Color.blue) && ($1.color == Color.blue) {
        $1
      } else if (($0.color == Color.blue) && ($1.color != Color.blue)) {
        $0
      } else { //leave them in same order
        $0
      }
    }
    

提交回复
热议问题