让我先说一下我是Ruby的新手(非常明显)。我在Codecademy上学习Ruby,并且我对sort函数感到困惑。以用作为例:
list = [3,2,1,4]
list.sort { |a,b| b <=> a }
我知道这将按降序返回数组 - [4,3,2,1]。我完全不明白为什么。我知道当调用sort函数时,数组中的数字会被传递到函数中并进行比较,然后返回-1,0或1 - 但是接着是什么?例如,我猜这是首先要比较的东西:
[3 <=> 2] = 1
但它对返回的1做了什么?在获得1后,数组会是什么样子?
我很困惑,因为我不明白如何逆转比较(a&lt; =&gt; b&b =&lt; a&gt; a)会改变数组的排序方向。除非我弄错了,否则不会&#34; 1&lt; =&gt; 2&#34;基本上返回&#34; 1来自2&#34;,而&#34; 2&lt; =&gt; 1&#34;返回&#34; 2来自1&#34;?这或多或少是相同的,但结果明显不同。
答案 0 :(得分:5)
“宇宙飞船”操作员<=>
不会返回“a a before b”之类的英语。它返回sort
需要知道的内容:两个元素相互关联的位置。具体来说,它返回您提到的-1,0或1值。
在a <=> b
中,如果a
小于b
(通过对a
为实例的类使用的比较方法),则返回 - 1。如果它们相等,则返回0;如果a
大于b
,则返回值为1.
执行b <=> a
时,返回的值基于b
而非a
,因此如果a较小,则会得到1,而在执行时得到-1 a <=> b
。
因此,虽然英语含义相同,但魔鬼在细节中:-1,0或1返回值。该值精确地告诉Ruby两个元素如何适合排序数组。
这三个数字的神奇之处在于Ruby使用的quicksort algorithm。尝试精确解释该算法的工作方式超出了范围,但您基本上可以将其视为对许多值的简单比较。对于数组中的每个项目,使用数组中的另一个项目调用<=>
,以确定两个项目相对于彼此的位置。一旦进行了足够的比较,所有这些单独项目的位置都是已知的,并且已完成排序。
作为一个简单的(并非技术上准确,但足够接近)示例,请考虑数组[3, 2, 7, 1]
。您可以获取一个值来比较其他值,以便开始排序。我们将选择3.运行3与所有其他数字的比较给我们:
3 <=> 2 == 1
:3大于2,因此2必须位于3的左侧。我们的数组现在可能如下所示:[2, 3, 7, 1]
3 <=> 7 == -1
:3小于7,因此7必须是3的右边。我们的数组继续看起来像之前一样,因为7已经在右边。3 <=> 1 == 1
:3大于1,因此1必须位于3的左侧。我们的数组现在看起来像这样:[2, 1, 3, 7]
我们知道7必须是正确的,因为它是“大于3”侧的唯一元素。所以我们只需要弄清楚3:1和2之前所有内容的排序顺序。运行类似的比较,我们显然将1和2交换为[1, 2, 3, 7]
。
我希望这有帮助!
答案 1 :(得分:1)
比较得到两个参数,如果第一个参数小于第二个参数则返回-1
,如果两个参数相等则返回0
,如果第二个参数更大则返回1
比第一个论点。交换两者时,它会反转结果。 <=>
并不关心其操作数的来源,因此虽然更改不会添加有关a
和b
之间关系的任何额外信息,但它会反转<=>
和(1 <=> 2) == -1
(2 <=> 1) == 1
之间的关系{1}},它反转了排序顺序。
1 <=> 2
作为排序功能,您不会获得2 <=> 1
或-1
;得到1
或{{1}}。从任何一个数字开始,您决定传递给比较的参数应该在结果的后面。
答案 2 :(得分:0)
除非我弄错了,否则不会&#34; 1&lt; =&gt; 2&#34;基本上返回&#34; 1来自2&#34;,而&#34; 2&lt; =&gt; 1&#34;返回&#34; 2来自1&#34;?这或多或少是相同的,但结果明显不同。
不,是的。问块的问题是:&#34;左边的元素是在右边之前还是之后?&#34;通过左右交换,您可以交换订单。
所以,答案是:你本身并没有扭转比较,但是你正在颠倒sort
方法的想法,哪个是剩下的,哪个是正确的。
块的返回值由sort
解释为:
0
:订单无关紧要1
:元素已按正确顺序排列-1
:元素的顺序错误通过左右交换,您可以交换块是否告诉sort
元素的顺序是正确还是错误。
请注意,Quicksort在这里完全不相关。重要的是比较器块的合同。然后Quicksort,Shellsort,Insertion Sort,Bubblesort,Bogosort,Timsort或其他基于比较的排序是否使用该块并不重要。