2011-01-21 16 views
3

RubyのArray#sort、デフォルトでは、その価値のために、このような数字を、ソートします:数字を単語のように並べ替えるにはどうすればよいですか?

[11, 12, 13, 112, 113, 124, 125, 127] 

彼らはアルファベット順にしている言葉であるかのように私は、このような数字の配列をソートしたいと思います:

[11, 112, 113, 12, 124, 125, 127, 13] 

どうすればいいですか? (最終的に、私はハッシュキーでこれをやりたがっているので、代わりにその方法に答える場合は問題ありません)また、この種の並べ替えの名前はありますか?

答えて

7

あなたはすべてのcrqzyある)))私は、このような解決策があります。

a.sort_by &:to_s 
+1

よりもこの質問から多くを学んだと思う。これは可能な限り最短の解決策である。 Ruby 1.9では、同じ方法で配列をソートすることもできます:a.sort_by!(&:tos) – psyho

+0

@psycho 'sort_by!'は1.9.2+のみです(1.9.1にはありません) – Phrogz

+0

これは存在する<333 – Matchu

2

まあ、1つの方法は、すべての値を文字列に変換してから変換することです。

a = [11, 12, 13, 112, 113, 124, 125, 127] 
a = a.map(&:to_s).sort.map(&:to_i) 
p a # => [11, 112, 113, 12, 124, 125, 127, 13] 
+0

ハ!まあ、それは簡単で賢いです。 :) –

+0

列挙型と比較して冗長で非効率的#sort_by ... – tokland

+0

@tokland:私の答えが最初に来ました;) 'sort_by'は将来私のツールボックスの一部になるでしょう! – Matchu

1

pass in a block 2つの引数を受け入れ、独自のカスタム定義比較関数の結果を返す並べ替えを行うことができます。この例はそれ自体について話すべきですが、何か質問があればお気軽にお尋ねください。

a = [11, 112, 113, 12, 124, 125, 127, 13] 
new_a = a.sort do |x,y| 
    "%{x}" <=> "%{y}" 
end 
puts new_a 

注:私はあなたがソートするオブジェクトを中心にIntegerのではありませんので、あなたが解決策のこの種を探している理由があると思われます。 Integerをサブクラス化することは意味があり、意味的により喜ばしいことかもしれません。インスタンス化は明らかに困難になりますが、少なくとも私にとっては正しいと感じます。

+1

私はこのメソッドも好きですが、これは将来拡張が容易なので+1です。しかし、パフォーマンスが上がるまでは、比較するたびにそれぞれを文字列に変換するよりも、各要素に合計2回の変換を行うのが最善でしょう。 – Matchu

+1

実際には、この違いはごくわずかです。より似たような結果を得るために2つのコードを修正しました(出力文を削除し、メソッド呼び出しに '!'を追加しました)。 10k回、私は私のために2.7s、あなたのために2.8sを得ました。 [プロファイラ出力](http://pastebin.com/raw.php?i=KYe766d9)を参照してください。 –

+0

あなたはそうではありません。実際には文字列のように使っているので、私の場合は 'Integer'をサブクラス化する必要はないと思います。しかし、私はそれが良い点だと思う。 –

関連する問題