代码之家  ›  专栏  ›  技术社区  ›  PJ.

如何根据不同订单的多个条件进行排序?

  •  18
  • PJ.  · 技术社区  · 17 年前

    我真的很想在不修补猴子的情况下处理这个问题,但是我还没有找到其他的选择。

    我有一个数组(在Ruby中),需要按多种条件排序。我知道如何使用排序方法,并且我使用了使用选项数组按多个条件排序的技巧。但是,在这种情况下,我需要第一个条件按升序排序,第二个条件按降序排序。例如:

    ordered_list = [[1, 2], [1, 1], [2, 1]]
    

    有什么建议吗?

    编辑:我刚刚意识到我应该提到,我不能很容易地比较第一个和第二个值(我实际上在这里处理对象属性)。因此,对于一个简单的例子,它更像是:

    ordered_list = [[1, "b"], [1, "a"], [2, "a"]]
    
    5 回复  |  直到 14 年前
        1
  •  33
  •   Brian Phillips    17 年前

    怎么样:

    
    ordered_list = [[1, "b"], [1, "a"], [2, "a"]]
    ordered_list.sort! do |a,b|
      [a[0],b[1]] <=> [b[0], a[1]]
    end
    
    
        2
  •  8
  •   TwoByteHero    14 年前

    我做了一个噩梦,想知道如何对一个特定的属性进行反向排序,但通常对另外两个属性进行排序。只是一个关于在这之后出现的那些被A,B块语法混淆的排序的注释。您不能使用 {|a,b| a.blah <=> b.blah} 块样式 sort_by! sort_by . 它必须与 sort! sort . 另外,如前所述,其他海报交换 a b 跨比较运算符 <=> 颠倒排序顺序。这样地:

    通常按blah和craw排序,但按bleu的相反顺序排序:

    something.sort!{|a,b| [a.blah, b.bleu, a.craw] <=> [b.blah, a.bleu, b.craw]}
    

    也可以使用 - 签到 索尔特比 索特比! 要对数字进行反向排序(据我所知,它只对数字有效,因此不要使用字符串,因为它只会出错并杀死页面)。

    假定 a.craw 是一个整数。例如:

    something.sort_by!{|a| [a.blah, -a.craw, a.bleu]}
    
        3
  •  4
  •   glenn mcdonald    17 年前

    我有同样的基本问题,通过添加以下内容解决了它:

    class Inverter
      attr_reader :o
    
      def initialize(o)
        @o = o
      end
    
      def <=>(other)
        if @o.is && other.o.is
          -(@o <=> other.o)
        else
          @o <=> other.o
        end
      end
    end
    

    这是一个包装器,它简单地反转<=>函数,然后允许您执行以下操作:

    your_objects.sort_by {|y| [y.prop1,Inverter.new(y.prop2)]}
    
        4
  •  4
  •   mislav Telemachus    17 年前

    Enumerable#multisort 是可应用于 任何尺寸 不是只有两个项目。参数是布尔值,指示特定字段应按升序还是降序排序(用法如下):

    items = [
      [3, "Britney"],
      [1, "Corin"],
      [2, "Cody"],
      [5, "Adam"],
      [1, "Sally"],
      [2, "Zack"],
      [5, "Betty"]
    ]
    
    module Enumerable
      def multisort(*args)
        sort do |a, b|
          i, res = -1, 0
          res = a[i] <=> b[i] until !res.zero? or (i+=1) == a.size
          args[i] == false ? -res : res
        end
      end
    end
    
    items.multisort(true, false)
    # => [[1, "Sally"], [1, "Corin"], [2, "Zack"], [2, "Cody"], [3, "Britney"], [5, "Betty"], [5, "Adam"]]
    items.multisort(false, true)
    # => [[5, "Adam"], [5, "Betty"], [3, "Britney"], [2, "Cody"], [2, "Zack"], [1, "Corin"], [1, "Sally"]]
    
        5
  •  2
  •   Alex Fortuna    16 年前

    我用格伦的食谱已经有一段时间了。厌倦了一次又一次地把代码从一个项目复制到另一个项目,我决定把它变成一块宝石:

    http://github.com/dadooda/invert