我真的不明白以下排序方法:
books = ["Charlie and the Chocolate Factory", "War and Peace", "Utopia", "A Brief History of Time", "A Wrinkle in Time"]
books.sort! { |firstBook, secondBook| firstBook <=> secondBook }
这是如何工作的?在ruby书中,它们有一个参数,例如|x|
表示数组中的每个值。如果有多个参数(本例中为firstBook和secondBook),它代表什么?
谢谢!
答案 0 :(得分:4)
<=>
运算符返回比较的结果。
因此"a" <=> "b"
返回-1,"b" <=> "a"
返回1,"a" <=> "a"
返回0.
这就是sort
能够确定元素顺序的方式。
答案 1 :(得分:1)
Array#sort(和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
(和sort!
)是如何覆盖排序的比较步骤的。比较有在排序过程中的某个时刻发生,以便弄清楚要放入什么顺序。在大多数情况下,你不需要覆盖比较,但是如果你这样做,这是允许的形式,所以它需要传递给块的两个项目:现在需要比较的两个项目。让我们看一个实际的例子:
[4, 3, 2, 1].sort{|x, y| puts "#{x}, #{y}"; x <=> y}
输出:
4, 2 2, 1 3, 2 3, 4
这告诉我们,在这种情况下,sort
比较4
和2
,然后2
和1
,然后3
和{ {1}},最后是2
和3
,以便对数组进行排序。精确的细节与此讨论无关,取决于所使用的排序算法,但同样,所有排序算法都需要能够比较项目才能进行排序。
答案 2 :(得分:0)
{}内给出的块作为方法排序的比较函数传递。 | a,b |告诉我们这个比较函数需要2个参数(这是我们需要比较的预期参数数量)。
对于数组中的每个元素执行此块,但如果我们需要多一个参数,则在此之后采用下一个元素。
答案 3 :(得分:0)
有关说明,请参阅http://ruby-doc.org/core-2.0/Array.html#method-i-sort。至于你书中提到的单参数方法,我只能猜你在看sort_by。你能举个例子吗?