【问题标题】:Sorting arrays in opposite order in Rby在 Rby 中以相反的顺序对数组进行排序
【发布时间】:2018-07-06 00:08:31
【问题描述】:

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

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

下面的代码块对这个数组进行排序booksA-Z

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

下面的代码块对这个数组进行排序booksZ-A

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

这是为什么?为什么第一个排序 A-Z 而第二个排序 Z-A?我有点理解组合比较运算符&lt;=&gt;。它根据比较返回 -1、1 或 0。但是这是如何排序的呢?谢谢!

【问题讨论】:

标签: arrays ruby sorting spaceship-operator


【解决方案1】:

排序运算符的作用类似于:它告诉您某事物是否小于、大于或等于排序顺序中的另一个对象。所以你的第一个块问“firstBooksecondBook 之前还是之后”,第二个块问“secondBook 是在first book 之前还是之后”。如您所见,答案是相反的:

  • “A”出现在之前“B”("A" &lt;=&gt; "B" == -1)
  • “B”出现在之后“A”("B" &lt;=&gt; "A" == 1)

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

【讨论】:

  • 所以我收集的是,如果一个字母在字母表中的后面,它具有更大的价值。所以像“A”“B”这样的东西会返回-1。因为“B”更大,所以 sort 把它放在最后吗?如果你做了“B”“A”返回1,它会把“B”放在开头吗?所以总的来说,如果返回1,第一个操作数会放在前面,如果返回-1,第一个操作数会放在后面?
  • 是的,差不多。 (我认为你倒退了,较小的值先于较大的值,所以smaller &lt;=&gt; larger == -1)。比较排序算法总是一次查看两个项目并找出哪个先出现。 Ruby 在排序时使用值-101 来指示这一点。不过,在 ruby​​ 中,您可以劫持这种行为并根据您的选择进行排序,因此“更小”和“更大”取决于您。这就是为什么你可以将一个块传递给sort
【解决方案2】:

排序算法使用块的返回值,在这种情况下它是比较运算符的结果(&lt;=&gt;)。当-1 返回时,ab 的顺序将保持不变(即ab之前出现,取决于值,算法将保持ab 的当前顺序要知道a 是否应该排在b 之前(-1),还是之后(1),或者两者是否相等(0)。

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

让我们添加一些输出,看看当您对图书列表调用 sort 时会发生什么。这将使我们对 sort 方法的作用有所了解。我添加了 cmets 来说明排序的每个步骤是如何改变书籍数组的。请注意,在这个例子中,关于如何排序“交换”位置被简化了。

> 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 &lt;=&gt; b 更改为 b &lt;=&gt; 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! 的文档

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    相关资源
    最近更新 更多