在Swift中,排序方法如何反向工作?

在Swift中,排序方法如何反向工作?,swift,Swift,因为参数是传递给向后函数的,所以很难理解发生了什么。此代码是如何工作的?发送到数组的排序方法将成对获取该数组的元素,并决定哪一个先到。通过将该方法应用到数组的所有元素,它最终会得到一个排序数组 但“先来”是什么意思?这可能意味着什么!事实是,你可以决定它的含义。要告诉排序后的方法“先到”是什么意思,可以将其作为参数传递给函数,该函数接受两个元素并返回一个Bool,说明第一个元素是否“先到” 那么,向后就是这样一个函数: let names = ["Chris", "Alex", "Ewa", "

因为参数是传递给向后函数的,所以很难理解发生了什么。此代码是如何工作的?

发送到数组的
排序方法将成对获取该数组的元素,并决定哪一个先到。通过将该方法应用到数组的所有元素,它最终会得到一个排序数组

但“先来”是什么意思?这可能意味着什么!事实是,你可以决定它的含义。要告诉排序后的
方法“先到”是什么意思,可以将其作为参数传递给函数,该函数接受两个元素并返回一个Bool,说明第一个元素是否“先到”

那么,
向后
就是这样一个函数:

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


func backward(_ s1: String, _ s2: String) -> Bool {
     return s1 > s2
}
var reversedNames = names.sorted(by: backward)
// reversedNames is equal to ["Ewa", "Daniella", "Chris", "Barry", "Alex"]
backward
函数表示:第一个参数仅在大于第二个参数时才相对于第二个参数“优先”

现在我们将
backward
函数交给
sorted
方法:

func backward(_ s1: String, _ s2: String) -> Bool {
    return s1 > s2
}
请注意,
backward
没有调用
backward
函数;它是
向后
函数的名称。我们将函数本身交给排序后的,这样它就知道“先到”是什么意思了

因此,
sorted
最终返回一个数组,其中每个较大的元素相对于每个较小的元素“排在第一位”。对于字符串,“较大”表示“字母表中的后面”,因此我们得到
[“Ewa”、“Daniella”、“Chris”、“Barry”、“Alex”]
非常好。请将其保留为已接受的答案。我想再详细介绍一下

当您将函数
向后
传递到
sorted()
时,在后台,在您看不到的代码中,它会多次调用
向后
,以比较两个项目。要公开此行为,请将
print
语句添加到
backward

var reversedNames = names.sorted(by: backward)
然后,当您运行时:

func backward(_ s1: String, _ s2: String) -> Bool {
     print("backward comparing \(s1) and \(s2)")
     return s1 > s2
}
你会看到:

因此,即使我们没有看到
sorted()
code,它显然多次调用
backward
来比较项目,以便对它们进行排序

有许多排序算法,但它们都有一个共同点。在排序过程中,有必要一次比较两个项目


案例研究:插入排序

让我们看看一个真正的排序算法,以及它是如何使用排序函数的 你通过了

下面是一个插入排序的实现,这是一个非常简单的算法。假设你有五张扑克牌要分类

  • 将卡片放在桌子上,然后拿起左手的第一张。你左手中的牌是分类好的牌。由于您只有一张,因此默认情况下会对左手中的牌进行排序
  • 现在用右手拿起第二张卡片,将其插入左手的正确位置。为此,您必须将右手中的卡与左手中的卡进行比较,以找到正确的插入点。因为你只有两张牌,你只需要比较它们来决定新牌是在第一张牌之前还是之后
  • 继续这一过程,拿起一张牌并将其插入桌子上每张牌的正确位置,直到你左手拿着所有的牌
  • 您左手中的牌现在已排序
  • 以下是插入排序:

    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
    

    因此,您可以看到传递给
    insertionSort()
    的函数用于确定项目的顺序。正如@matt所说,通过使用一个函数,排序可以让你决定前面是什么意思。

    查看此repo以了解Swift中的高阶函数:也可以编写
    名称。排序(按:>)
    老实说,我理解了50%,但我仍然怀疑术语backword是否不是函数调用,还有什么,我已经添加了一个答案,它扩展了
    sorted
    如何使用
    backward
    “如果术语backword不是函数调用,那么它是什么?”它是函数引用。
    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
    
    // 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
    }
    
    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"]