📝
Ruby sortメソッドで配列を並び替える
今日は、sortメソッドを試用した配列の並び替えについてアウトプットします。
基本構文
配列.sort
とすると、昇順で並び替えた結果の配列を返してくれます。
文字列の場合や数字の場合など、実行例は下記のようになります。
# 文字列はabc順
irb(main):001:0> ary1 = [ "d", "a", "e", "c", "b" ]
=> ["d", "a", "e", "c", "b"]
irb(main):002:0> ary1.sort
=> ["a", "b", "c", "d", "e"]
# 数値は小→大
irb(main):003:0> ary2 = [2, 4, 1, 6, 5, 3]
=> [2, 4, 1, 6, 5, 3]
irb(main):004:0> ary2.sort
=> [1, 2, 3, 4, 5, 6]
# 降順にしたいときはreverseメソッドを使います
irb(main):005:0> ary2.sort.reverse
=> [6, 5, 4, 3, 2, 1]
# もとの配列は変更されません
irb(main):006:0> ary2
=> [2, 4, 1, 6, 5, 3]
# 破壊的メソッドsort!の場合
irb(main):012:0> ary2.sort!
=> [1, 2, 3, 4, 5, 6]
irb(main):013:0> ary2
=> [1, 2, 3, 4, 5, 6]
ブロックを使う場合
ブロックを用いて比較方法を定義することもできます。
ブロックにはa,bの2つの引数を渡して、比較方法の定義に<=>演算子
を利用します。
<=> 演算子
値が大きければ-1、等しければ0、小さければ1を返す比較演算子
また、比較が出来なかった場合はnilが返されます。
irb(main):001:0> 1 <=> 5 # 右の方が大きいので負の数を返す
=> -1
irb(main):002:0> 5 <=> 1 # 左の方大きいので正の数を返す
=> 1
irb(main):003:0> 5 <=> 5 # どちらも同じなので 0 を返す
=> 0
irb(main):005:0> 1 <=> "a" # 比較出来ない時は nil を返す
=> nil
irb(main):006:0> ary2
=> [2, 4, 1, 6, 5, 3]
# 配列.sortと同じ結果になる書き方
irb(main):007:0> ary2.sort{ |a, b| a <=> b }
=> [1, 2, 3, 4, 5, 6]
# reversメソッドを使用した場合と同じになる書き方
irb(main):008:0> ary2.sort{ |a, b| b <=> a }
=> [6, 5, 4, 3, 2, 1]
# 応用編:文字列になっている数字を並び替え
irb(main):009:0> ary3 = ["9", "7", "10", "11", "8"]
=> ["9", "7", "10", "11", "8"]
# 普通にsortするとこうなる
irb(main):010:0> ary3.sort
=> ["10", "11", "7", "8", "9"]
# ブロックを用いて、to_iメソッドを併用する
irb(main):011:0> ary3.sort{ |a, b| a.to_i <=> b.to_i }
=> ["7", "8", "9", "10", "11"]
# sort_byメソッドでさらにシンプルな書き方も可能
irb(main):013:0> ary3.sort_by {|v| v.to_i}
=> ["7", "8", "9", "10", "11"]
# sort_byメソッドのもう少し応用的な使用例
# 大文字と小文字が混じった文字列を昇順でソートする ※ただのsortだと大文字が優先される
irb(main):011:0> ["BAR", "FOO", "bar", "foo"].sort
=> ["BAR", "FOO", "bar", "foo"]
irb(main):010:0> ["BAR", "FOO", "bar", "foo"].sort_by {|v| v.downcase }
=> ["BAR", "bar", "FOO", "foo"]
参考
Discussion