在Rby中以相反的顺序对数组进行排序

Sorting arrays in opposite order in Rby

我是 Ruby 的新手,需要一段代码向我解释。要排序的数组是这个:

books = ["Charlie and the Chocolate Factory", "War and Peace", "Utopia", 
"A Brief History of Time", "A Wrinkle in Time"]

下面的代码块对该数组进行排序 books A-Z

books.sort! { |firstBook, secondBook| firstBook <=> secondBook }

下面的代码块对该数组进行排序 books Z-A

books.sort! { |firstBook, secondBook| secondBook <=> firstBook }

这是为什么?为什么第一个排序 A-Z 而第二个排序 Z-A?我有点理解组合比较运算符 <=>。它 returns -1、1 或 0 取决于比较。但是,这是如何排序的呢?谢谢!

排序运算符看起来像这样:它告诉您某个对象是否小于、大于或等于排序顺序中的另一个对象。所以你的第一个块问 "Is firstBook before or after secondBook",第二个块问 "is secondBook is before or after first book"。如您所见,答案是相反的:

  • "A"在之前 "B" ("A" <=> "B" == -1)
  • "B"在之后 "A" ("B" <=> "A" == 1)

所以如果你颠倒问题的顺序,你会得到相反的答案,这意味着(比较类型)sort algorithm给出相反的结果。

排序算法使用块中的 return 值,在本例中它是比较运算符 (<=>) 的结果。当 -1 为 return 时,ab 的顺序将保持不变(即 ab 之前,具体取决于算法的值将保留 ab 的当前顺序以了解 a 应该排在 b 之前(-1),还是排在之后(1), 或者两者等价 (0).

算法反复比较相邻的元素对,直到所有元素都有序。

让我们添加一些输出,看看当您对图书列表调用 sort 时会发生什么。这将使我们对排序方法的作用有所了解。我添加了注释来说明排序的每个步骤如何改变 books 数组。请注意,在本示例中讨论如何简化排序 "swaps" 个位置。

> books = ["Charlie and the Chocolate Factory", "War and Peace", "Utopia", "A Brief History of Time", "A Wrinkle in Time"]
> books.sort! do |a, b|
>   result = a <=> b
>   puts %(\n"#{ a }" <=> "#{ b }"  #=> #{ result })  # Print out which elements are being compared and the result
>   result
> end

"Charlie and the Chocolate Factory" <=> "War and Peace"  #=> -1
# ["Charlie and the Chocolate Factory", "War and Peace", "Utopia", "A Brief History of Time", "A Wrinkle in Time"]  *** No change

"War and Peace" <=> "Utopia"  #=> 1
# ["Charlie and the Chocolate Factory", "Utopia", "War and Peace", "A Brief History of Time", "A Wrinkle in Time"]  *** Positions of "Utopia" and "War and Peace" are swapped

"Charlie and the Chocolate Factory" <=> "Utopia"  #=> -1
# ["Charlie and the Chocolate Factory", "Utopia", "War and Peace", "A Brief History of Time", "A Wrinkle in Time"]  *** No change

"War and Peace" <=> "A Brief History of Time"  #=> 1
# ["Charlie and the Chocolate Factory", "Utopia", "A Brief History of Time", "War and Peace", "A Wrinkle in Time"]  *** Positions of "War and Peace" and "A Brief History of Time" are swapped

"Utopia" <=> "A Brief History of Time"  #=> 1
# ["Charlie and the Chocolate Factory", "A Brief History of Time", "Utopia", "War and Peace", "A Wrinkle in Time"]  *** Positions of "Utopia" and "A Brief History of Time" are swapped

"Charlie and the Chocolate Factory" <=> "A Brief History of Time"  #=> 1
# ["A Brief History of Time", "Charlie and the Chocolate Factory", "Utopia", "War and Peace", "A Wrinkle in Time"]  *** Positions of "Charlie and the Chocolate Factory" and "A Brief History of Time" are swapped

"War and Peace" <=> "A Wrinkle in Time"  #=> 1
# ["A Brief History of Time", "Charlie and the Chocolate Factory", "Utopia", "A Wrinkle in Time", "War and Peace"]  *** Positions of "War and Peace" and "A Wrinkle in Time" are swapped

"Utopia" <=> "A Wrinkle in Time"  #=> 1
# ["A Brief History of Time", "Charlie and the Chocolate Factory", "A Wrinkle in Time", "Utopia", "War and Peace"]  *** Positions of "Utopia" and "A Wrinkle in Time" are swapped

"Charlie and the Chocolate Factory" <=> "A Wrinkle in Time"  #=> 1
# ["A Brief History of Time", "A Wrinkle in Time", "Charlie and the Chocolate Factory", "Utopia", "War and Peace"]  *** Positions of "Charlie and the Chocolate Factory" and "A Wrinkle in Time" are swapped

"A Brief History of Time" <=> "A Wrinkle in Time"  #=> -1
# ["A Brief History of Time", "A Wrinkle in Time", "Charlie and the Chocolate Factory", "Utopia", "War and Peace"]  *** No change

# Done! All elements have been sorted, so the algorithm exits.

=> ["A Brief History of Time", "A Wrinkle in Time", "Charlie and the Chocolate Factory", "Utopia", "War and Peace"]

当比较从 a <=> b 更改为 b <=> a 时,结果会反转,从而导致排序以相反的顺序进行。

> books = ["Charlie and the Chocolate Factory", "War and Peace", "Utopia", "A Brief History of Time", "A Wrinkle in Time"]
> books.sort! do |a, b|
>   result = b <=> a
>   puts %(\n"#{ b }" <=> "#{ a }"  #=> #{ result })  # Print out which elements are being compared and the result
>   result
> end

"A Wrinkle in Time" <=> "A Brief History of Time"  #=> 1

"Charlie and the Chocolate Factory" <=> "A Brief History of Time"  #=> 1

"Charlie and the Chocolate Factory" <=> "A Wrinkle in Time"  #=> 1

"Utopia" <=> "A Brief History of Time"  #=> 1

"Utopia" <=> "A Wrinkle in Time"  #=> 1

"Utopia" <=> "Charlie and the Chocolate Factory"  #=> 1

"War and Peace" <=> "A Brief History of Time"  #=> 1

"War and Peace" <=> "A Wrinkle in Time"  #=> 1

"War and Peace" <=> "Charlie and the Chocolate Factory"  #=> 1

"War and Peace" <=> "Utopia"  #=> 1
=> ["War and Peace", "Utopia", "Charlie and the Chocolate Factory", "A Wrinkle in Time", "A Brief History of Time"]

另请参阅 Array#sort!

的文档