【问题标题】:why does array.sort{|x,y| y <=> x} sort the array in descending order in Ruby?为什么 array.sort{|x,y| y <=> x} 在Ruby中按降序对数组进行排序?
【发布时间】:2014-07-11 01:39:06
【问题描述】:

我最近遇到了一段代码

array.sort{|x,y| y <=> x}

按降序对整数数组进行排序。我查看了 运算符并了解到它返回三个不同的值,-1、0 或 1,具体取决于一个值是否小于、大于或等于另一个值。

但我无法解释为什么上面的代码会按降序对数组进行排序,但我知道这肯定要归功于 IRB。这里发生了什么?谁能给我解释一下?

【问题讨论】:

    标签: ruby arrays sorting


    【解决方案1】:

    出于同样的原因:

    array.sort{|x,y| x <=> y}
    

    按升序排列。


    以这个程序为例:

    [1,5,2,4,3].sort do |x,y|
      puts "---"
      puts x
      puts y
      puts x <=> y
      x <=> y
    end
    

    它将输出它正在比较的两个数字,然后在排序过程中输出&lt;=&gt; 的结果。它输出这个:

    ---
    1
    2
    -1 # 1 is less than 2
    ---
    2
    3
    -1 # 2 is less than 3
    ---
    5
    2
    1 # 5 is greater than 1
    ---
    4
    2
    1 # 4 is greater than 2
    ---
    5
    4
    1 # 5 is greater than 4
    ---
    4
    3
    1 # 4 is greater than 3
    

    如果您将x &lt;=&gt; y 的顺序颠倒为y &lt;=&gt; x,您将得到相反的结果。

    【讨论】:

    • 谢谢。我知道如果 x 和 y 颠倒,它将按升序排序。我只是不明白 的来源。所以它基本上遍历数组中的每个值,然后将其映射到一个新数组中,比如......洗牌一副牌,无序的牌在你的手指后面,然后从无序的牌堆中抽出每张牌,检查它应该放在你正在查看的牌堆的前面还是后面?
    • 它不是这样做的——排序算法听起来像插入排序,并且比 ruby​​ 使用的快速排序算法慢
    【解决方案2】:

    因为你做了 y x,而不是 x y。论据的顺序很重要。

    【讨论】:

      【解决方案3】:

      我选择了一个我希望大多数 Ruby 新手都能理解的答案。

      Array#sort 比较数组中的每一对元素。对于每对元素x,ysort 的块返回-1 如果x 在排序中在y 之前,1 如果yx0 之前另一个。如果没有给出块,sort 使用块:

      { |x,y| x <=> y }
      

      例如,如果 xy 是字符串,则方法 String#<=> 可能会这样定义:

      class String
        def <=>(other)
          case
          when self < other then -1
          when self > other then  1
          else 0
          end
        end
      end
      

      同样,如果xy 是数组,则调用Array#<=>,依此类推。对于Fixnums、Bignums 和Floats(所有这些都来自Numeric 的后代类),使用了Numeric#<=> 方法,因此被排序的数组可以包含这些的混合三种数据类型。

      如果sort的块是:

      { |x,y| y <=> x }
      

      块返回此处显示的值(与默认x &lt;=&gt; y 的值进行比较):

      现在假设我们希望对数组[2,3,1,2] 进行排序。对于默认的sort,带有x &lt;=&gt; y 的排序块返回此处显示的值:

      这会导致sort 返回[1,2,2,3]。如果排序块是

      { |x,y| y <=> x }
      

      排序块返回这些值:

      导致sort 返回[3,2,2,1]

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-05-26
        • 2015-11-08
        • 2017-07-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-26
        • 2011-02-14
        相关资源
        最近更新 更多