複数の条件で異なる順序で並べ替えるにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/73032

  •  09-06-2019
  •  | 
  •  

質問

本当はモンキーパッチを適用せずにこれを処理したいのですが、別のオプションがまだ見つかりません。

複数の条件で並べ替える必要がある配列 (Ruby 内) があります。私はsortメソッドの使用方法を知っており、オプションの配列を使用して複数の条件で並べ替えるトリックを使用しました。ただし、この場合は、最初の条件で昇順に並べ替え、2 番目の条件で降順で並べ替える必要があります。例えば:

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

助言がありますか?

編集:最初の値と 2 番目の値を簡単に比較できないことに気付きました (ここでは実際にオブジェクト属性を使用しています)。簡単な例としては次のようになります。

ordered_list = [[1, "b"], [1, "a"], [2, "a"]]
役に立ちましたか?

解決

どうでしょうか:


ordered_list = [[1, "b"], [1, "a"], [2, "a"]]
ordered_list.sort! do |a,b|
  [a[0],b[1]] <=> [b[0], a[1]]
end

他のヒント

特定の属性を逆ソートし、他の 2 つを通常はソートする方法を見つけようとして、悪夢のような日々を過ごしていました。この後にやって来て、| 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]}

を使用することも可能です。 - と署名する sort_by または sort_by! 数字に対して逆ソートを実行します(私が知っている限り、それは数字に対してのみ機能するため、エラーが発生してページが強制終了されるだけなので、文字列では試さないでください)。

仮定する a.craw は整数です。例えば:

something.sort_by!{|a| [a.blah, -a.craw, a.bleu]}

私もこれと同じ基本的な問題を抱えていましたが、これを追加することで解決しました。

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)]}

Enumerable#multisort の配列に適用できる汎用ソリューションです。 任意のサイズ, 、2つのアイテムを持つものだけではありません。引数は、特定のフィールドを昇順または降順のどちらで並べ替えるかを示すブール値です (使用法は以下を参照)。

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"]]

私はグレンのレシピをかなり長い間使用しています。プロジェクトからプロジェクトへコードを何度もコピーするのにうんざりしたので、それを gem にすることにしました。

http://github.com/dadooda/invert

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top