次のような値を持つ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"
ます。なぜそれが起こるのかわかりません
次のような値を持つ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"
ます。なぜそれが起こるのかわかりません
シュワルツ変換(Enumerable#sort_by)を使用し、整数の配列(Array#<=>)で定義された辞書式順序を利用します。
sorted_ips = ips.sort_by { |ip| ip.split(".").map(&:to_i) }
もう少し詳しく説明していただけますか?
数字を含む文字列を比較することはできません:"2" > "1"
、はい。ただし"11" < "2"
、文字列は辞書式順序で比較されるため、辞書の単語のようになります。したがって、IPを比較できるもの(整数の配列)に変換する必要がありますip.split(".").map(&:to_i)
。たとえば、"1.2.10.3"
に変換され[1, 2, 10, 3]
ます。この変換をと呼びましょうf
。
Enumerable#sort
これで:を使用できますが、代わりにips.sort { |ip1, ip2| f(ip1) <=> f(ip2) }
上位の抽象化を使用できるかどうかを常に確認してください。Enumerable#sort_by
この場合:ips.sort_by { |ip| f(ip) }
。「を取り、マッピングips
で定義された順序で並べ替える」と読むことができます。f
で分割して、データをチャンクに分割し'.'
ます。それ自体を行うための標準関数はないため、これを実行するにはカスタムソートを作成する必要があります。
また、データを文字列として取得し、ASCII比較を行っているため、2.0.1.10
前に説明した動作が予想され、結果が表示されます。2.0.1.5
arr1 = "2.0.0.1".split('.')
arr2 = "2.0.0.6".split('.')
入力内のすべてのデータについて、要素ごとにarr1
との両方を比較します。arr2