不带块调用的Array#sort (and sort!
) 将与 进行比较<=>
,因此该块是多余的。这些都完成了同样的事情:
books.sort!
books.sort_by!{|x| x}
books.sort!{|firstBook, secondBook| firstBook <=> secondBook}
由于您没有覆盖默认行为,因此第二种和第三种形式不必要地复杂。
那么这一切是如何运作的呢?
第一种形式通过使用某种排序算法对数组进行排序——哪个不相关——它需要能够比较两个元素来决定哪个先出现。(下面有更多内容。)它在幕后自动遵循与上面第三行相同的逻辑。
中间的表格让您选择要排序的内容。例如:您可以对每个项目的长度进行排序,而不是对每个项目进行排序(这是默认设置):
books.sort_by!{|title| title.length}
然后books
从最短的标题到最长的标题排序。如果您所做的只是在每个项目上调用一个方法,那么还有另一个可用的快捷方式。这做同样的事情:
books.sort_by!(&:length)
在最终形式中,您可以控制比较本身。例如,您可以向后排序:
books.sort!{|first, second| second <=> first}
为什么sort
需要将两个项目传递到块中,它们代表什么?
Array#sort
(and sort!
) with a block 是您如何覆盖排序的比较步骤。比较必须在排序过程中的某个时刻进行,以便确定将事物放入的顺序。在大多数情况下,您不需要覆盖比较,但如果您这样做,这是允许这样做的形式,所以它需要将两个项目传递到块中:现在需要比较的两个项目。让我们看一个实际的例子:
[4, 3, 2, 1].sort{|x, y| puts "#{x}, #{y}"; x <=> y}
这输出:
4, 2
2, 1
3, 2
3、4
这向我们表明,在这种情况下,sort
比较4
and 2
, then 2
and 1
, then 3
and 2
,然后 finally 3
and 4
,以便对数组进行排序。确切的细节与此讨论无关,取决于所使用的排序算法,但同样,所有排序算法都需要能够比较项目才能进行排序。