2

次のような値を持つRubyの配列があります

xs = %w(2.0.0.1
2.0.0.6
2.0.1.10
2.0.1.5
2.0.0.8)

等々。最終結果が次のようになるように配列をソートしたい:

ys = %w(2.0.0.1
2.0.0.6
2.0.0.8
2.0.1.5
2.0.1.10)

array.sort関数を使用してみましたが、"2.0.1.10"前に配置され"2.0.1.5"ます。なぜそれが起こるのかわかりません

4

2 に答える 2

18

シュワルツ変換Enumerable#sort_by)を使用し、整数の配列(Array#<=>)で定義された辞書式順序を利用します。

sorted_ips = ips.sort_by { |ip| ip.split(".").map(&:to_i) }

もう少し詳しく説明していただけますか?

  1. 数字を含む文字列を比較することはできません:"2" > "1"、はい。ただし"11" < "2"、文字列は辞書式順序で比較されるため、辞書の単語のようになります。したがって、IPを比較できるもの(整数の配列)に変換する必要がありますip.split(".").map(&:to_i)。たとえば、"1.2.10.3"に変換され[1, 2, 10, 3]ます。この変換をと呼びましょうf

  2. Enumerable#sortこれで:を使用できますが、代わりにips.sort { |ip1, ip2| f(ip1) <=> f(ip2) }上位の抽象化を使用できるかどうかを常に確認してください。Enumerable#sort_byこの場合:ips.sort_by { |ip| f(ip) }。「を取り、マッピングipsで定義された順序で並べ替える」と読むことができます。f

于 2012-12-21T19:34:05.763 に答える
1

で分割して、データをチャンクに分割し'.'ます。それ自体を行うための標準関数はないため、これを実行するにはカスタムソートを作成する必要があります。

また、データを文字列として取得し、ASCII比較を行っているため、2.0.1.10前に説明した動作が予想され、結果が表示されます。2.0.1.5

arr1 = "2.0.0.1".split('.')
arr2 = "2.0.0.6".split('.')

入力内のすべてのデータについて、要素ごとにarr1との両方を比較します。arr2

于 2012-12-21T19:32:57.203 に答える