2010-11-26 16 views
25

別の配列で指定された順序で配列をソートする必要があります。Rubyで配列を特定の順序で並べ替えるにはどうすればいいですか?

EX:すなわち

a.each do |t| 
    # It should be in the order of 'b' 
    puts t 
end 

ので、出力は

two 
one 
three 
する必要があり、 '' 'B' のために、今、私は配列をソートしたい配列

a=["one", "two", "three"] 
b=["two", "one", "three"] 

を考えます

提案がありますか?

+2

これはそのままですが、この質問は意味がありません。この例では、正確に同じ値を持つ2つの配列を示しています(順序が異なる)。 'b'で見つかった順序で' a'の要素を反復したい場合は、 'b'を繰り返してやりましょう:-)だから、もっと条件があると思います。配列の項目が一致しないのでしょうか?オブジェクト間の「==」ではないが、必要なものは異なる種類の平等ですか?いくつかのより意味のある例を示します。 – tokland

答えて

45

Array#sort_byはあなたが何をしているかです。コメントに応答して

a.sort_by do |element| 
    b.index(element) 
end 

よりスケーラブルなバージョン:

a=["one", "two", "three"] 
b=["two", "one", "three"] 

lookup = {} 
b.each_with_index do |item, index| 
    lookup[item] = index 
end 

a.sort_by do |item| 
    lookup.fetch(item) 
end 
+1

小さな配列では最も簡単ですが、問題がO(n)の場合はO(n^2)です。 – tokland

+0

@toklandよりスケーラブルなバージョンを提供しました。 –

+0

正確には、補助マッピング+ sort_byを作成します。おそらく 'lookup = Hash [b.to_enum.with_index]'と書いていますが、これは単なる詳細です。 Btw、あなたはその質問に私のコメントを見ましたか?あなたはOPが心に持っていたことを覚えていますか? – tokland

12

baのすべての要素が含まれており、要素が一意である場合、場合:aを想定し

puts b & a 
+0

この条件が成り立つと、 'b&a == b'。 –

+1

@PanThomakos、それは要素を含むことができ、また他のものを持つことができます。 – Nakilon

+1

私はこれがうまくいくと思いますが、ここに私の予約があります: "%s { 1.&(交差の設定)を使用して配列を並べ替えるのは誤解を招きます。 2.コードは脆いです。リストに重複した要素がある場合や、間違ったサイズの場合は、コードが破損します。 &の実装が要素がもはやソートされないように変更すると、コードが壊れます。 –

8

をソートします要素の順序に関してb

sorted_a = 
a.sort do |e1, e2| 
    b.index(e1) <=> b.index(e2) 
end 

私は通常これを使用して、エラーメッセージをActiveRecordに並べ替え、フォーム上のフィールドの表示順に並べ替えます。

+1

'sort_by'を使うときに' sort'を使うのはなぜですか? –

+0

パフォーマンス。 http://ruby-doc.org/core/classes/Enumerable.html#M003120ベンチマークを確認してください。 – Chirantan

+2

私のベンチマークは 'sort'の' N'秒、 'sort_by'のための' 0.07N'秒、 '&'の '0.01N'秒を示しています。 – Nakilon

関連する問題