首先,这个问题不是“0美元的意思”。我在swift文档中了解到$ 0就像索引一样。
我的问题是“如何使用numbers.sort { $0 > $1 }
来实现排序功能”。我在其他一些网站中搜索了这种语法numbers.sort { $0 > $1 }
,例如this one。它显然不是当前的版本。所以我仍然无法理解它的含义。
print(numbers) //[20, 19, 1, 12]
let sortedNumbers = numbers.sort { $0 > $1 }
print(sortedNumbers) //[20, 19, 12, 1]
有人可以为我解释上面这段简单的代码吗?就像这个简单的代码$0 > $1
如何实现sort函数一样,将数字从大到小排序。
我对索引有所了解,而 $ 0 看起来像索引,但它只有 $ 0 和 $ 1 两个索引。那怎么能用到4个数字呢?根据我之前在C ++中的知识,我无法理解其中的原理。
请尽可能以具体作出答案。谢谢!
-----------------以下是编辑的额外部分-------------------
我不知道stackoverflow是否允许我像这样编辑我的问题,但是这个额外的部分太长了,所以我不能在评论中添加它。 @pbodsk @Paul Richter
所以swift中的sort()语法使用快速排序来处理排序函数?
其实我的问题更多的是关于“sort{$0 > $1}
的操作原理是什么”。我知道你的意思,我认为这与swift 2.1文件所说的相似,但你的回答并不是我真正想知道的。对不起,我的英文表达不是很好。让我尝试另一种方式。
当我以前学习C ++时,总会有一些文档来解释函数的操作原理是什么,或者这个函数(如 sort())在后台运行。 Sort()这里需要比较第一次和第二次交换。在C ++中,它就像
if numbers[1] < numbers[2]{ //just consider this pseudocode
int k;
k = numbers[1];
numbers[1] = numbers[2];
numbers[2] = k;
}
我们可以看到这个过程是显而易见的。在swift中,它就像
numbers.sort({(val1: Int, val2: Int) -> Bool in
return val1 > val2
})
比较哪里?它是如何互换的? return val1 > val2
会自动比较并交换这两个值并返回它们吗?只需这一个语法就可以实现这3个进程吗?怎么样?这是我真正想知道的。对于我糟糕的英语表达再次抱歉。
答案 0 :(得分:24)
@the_UB和@moonvader都是正确的,但我只是想我会从@moonvader中扩展一下这个例子,只是为了告诉你我们如何最终得到sort
如果你看一下&#34; Swift编程语言&#34;中的例子。关于Closure Expressions您可以看到对您调用let numbers = [4, 6, 8, 1, 3]
方法的数组进行排序,然后可以将函数作为参数。
此函数必须接受两个参数并进行比较,然后返回一个布尔值。
所以如果我们有这个数组:
func sortBackwards(val1: Int, val2: Int) -> Bool {
print("val1: \(val1) - val2: \(val2)" )
return val1 > val2
}
和这个方法
numbers.sort(sortBackwards) //gives us [8, 6, 4, 3, 1]
我们可以对元素进行排序:
sort
sortBackwards
方法将对数组中的每个元素使用我们的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
sort
好的,让我们减少它。
我们可以直接将其作为参数添加到numbers.sort({(val1: Int, val2: Int) -> Bool in
return val1 > val2
})
方法中,而不是定义函数,如下所示:
Int
我们最终还是[8,6,4,3,1](多么幸运!)
好的,接下来我们可以做的是&#34; Swift编程语言&#34; (上面的链接)被称为&#34;从上下文中推断类型&#34;。当我们在val1
s数组上调用此方法时,Swift可以确定我们的val2
和Int
参数也必须是numbers.sort({val1, val2 in
return val1 > val2
})
s,那里没有我们需要告诉它。所以,让我们删除类型。这让我们:
return
结果仍然相同。
好的,到那儿。接下来我们可以做的是书中的内容被称为&#34;来自单表达式闭包的隐式返回&#34;
由于我们的比较可以在一行中完成,因此我们无需使用numbers.sort({val1, val2 in val1 > val2})
。所以:
val1
仍然给我们[8,6,4,3,1]
最后,我们要了解@moonvader使用更少的单词来解释:-)即&#34;速记参数名称&#34;
正如书中所说:
Swift自动为内联闭包提供简写参数名称,可用于通过名称$ 0,$ 1,$ 2等来引用闭包参数的值。
因此,在我们的示例中,$0
可以替换为val2
,而$1
可以替换为numbers.sort({$0 > $1})
这给了我们:
numbers.sort{$0 > $1}
我们仍然得到[8,6,4,3,1]
然后我们可以继续使用&#34; Trailing Closure&#34;,这意味着如果函数的最后一个参数是闭包,我们可以添加该参数&#34; outside&#34;功能。
所以我们最终得到:
dataweave
结果仍然是[8,6,4,3,1]
希望有助于澄清事情。
答案 1 :(得分:1)
以下是所有需要知道的事项:Sort and Sorted。
更具体地说,排序可以是两种类型:升序和降序。
问 - 所以要做排序,我们需要什么?
A - 我们需要两个变量来容纳两个变量(我不知道它是否是正确的单词)
因此,在这种情况下,我们有两个变量$0
和$1
。这两者都是表示左右变量的缩写。两者都有助于排序。
&#34; >
&#34;会下降。
&#34; <
&#34;会提升。
答案 2 :(得分:1)
速记参数名称
Swift自动为内联闭包提供简写参数名称,可用于通过名称$ 0,$ 1,$ 2等来引用闭包参数的值。
如果在闭包表达式中使用这些简写参数名称,则可以从其定义中省略闭包的参数列表,并且将从期望的函数类型推断出简写参数名称的数量和类型。也可以省略in关键字,因为闭包表达式完全由其主体组成:
reversed = names.sort( { $0 > $1 } )
这里,$ 0和$ 1引用闭包的第一个和第二个String参数。
答案 3 :(得分:1)
对列表进行排序的过程包括重复对其元素进行重新排序,直到无需重新排序。现在有很多排序算法,但他们都以不同的方式做到这一点。那么元素如何重新排序?通过比较两个给定的元素,并确定哪个元素首先出现,并在需要时交换它们。
我们可以将整个重新排序和交换部分与比较部分分开,并编写一个排序函数来处理所有重复的重新排序内容,并且只需要调用者指定如何比较两个元素。如果列表由数字组成,那么比较它们的方法几乎总是如此,即只取其值。但是假设列表包含一些更复杂的东西,比如汽车。你如何比较两辆车?那么,您可以通过数字比较它们的最高速度来比较它们。或者他们的汽油里程。还是价格。
但是比较并不一定是数字。我们可以通过实际比赛来比较两辆车。我们可以比较两辆汽车只是说一个是蓝色而另一个是不是,蓝色的是先订购,如果两个都不是蓝色,它们按照原来的顺序排列。
我们可以提出各种方法来比较两辆车。然后排序算法可以对汽车列表进行排序,而不知道任何关于汽车的信息,只要我们呼叫者告诉它如何比较汽车 - 任何两辆给定的汽车。我们只需将该比较表达为返回布尔值的表达式,如果它是真的,则第一辆车在第二辆车之前订购,如果它是假的,则第一辆车在第二个。
回到数字,这是sort { $0 > $1 }
的含义,用Swift非常简洁的语法:&#34;排序,如果第一个元素是&gt;第二个,在第二个之前订购第一个。&#34;
你问过它如何只用两个索引对四个数字进行排序。 $ 0和$ 1没有绑定到列表[20,19,1,12]中的四个特定元素,它们被绑定到需要比较的任意两个给定数字,因为排序算法重复需要这样做。
有几点需要注意。首先,运营商&gt;必须为要排序的元素类型定义。在该示例中,元素是数字,并且&gt;确实是定义的。其次,sort函数指定boolean true在第二个之前对第一个进行排序,而不是相反,因此比较函数遵循该规范。第三,将最后计算的表达式作为要使用的布尔值。事先做出这两个假设可以使比较函数写得如此简洁。
因此,如果我们想通过比赛对它们进行排序,我们就可以这样写:
cars.sort {
winner_of_race_between($0, $1) == $0
// if the first car beats the second, it is sorted ahead
}
或独家蓝色:
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
}
}