質問
本当はモンキーパッチを適用せずにこれを処理したいのですが、別のオプションがまだ見つかりません。
複数の条件で並べ替える必要がある配列 (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 にすることにしました。