Ruby_Array_56

この記事は、以下のドキュメントを改変(自分なりに整理)して利用しています。

class Array (Ruby 3.1 リファレンスマニュアル)

インスタンスメソッド

sort -> Array
sort! -> self
sort {|a, b| ... } -> Array
sort! {|a, b| ... } -> self
  • 配列の内容をソートする
  • sortはソートされた配列を生成して返す
  • sort!はselfを破壊的にソートしてselfを返す
  • ブロックとともに呼び出されたときは、比較をブロックを用いて行う
    • ブロックに2つの要素を引数として与えて評価する
    • ブロックは<=>演算子と同様に整数を返すことが期待されている
      • 第一引数が大きいなら正の整数、等しいなら0、小さいなら負の整数を返す必要がある。比較できないときはnilを返す。
irb(main):001:0> arr = %w[e c a b d]
=> ["e", "c", "a", "b", "d"]

irb(main):002:0> arr.sort
=> ["a", "b", "c", "d", "e"]

irb(main):003:0> arr
=> ["e", "c", "a", "b", "d"]

irb(main):004:0> arr.sort!
=> ["a", "b", "c", "d", "e"]

irb(main):005:0> arr
=> ["a", "b", "c", "d", "e"]
irb(main):001:0> arr = %w[10 3 6 20 2 1]
=> ["10", "3", "6", "20", "2", "1"]

irb(main):002:0> arr.sort
=> ["1", "10", "2", "20", "3", "6"]

irb(main):003:0> arr.map(&:to_i).sort
=> [1, 2, 3, 6, 10, 20]

irb(main):004:0> arr.sort { |a, b| a.to_i <=> b.to_i }
=> ["1", "2", "3", "6", "10", "20"]

irb(main):005:0> arr
=> ["10", "3", "6", "20", "2", "1"]

irb(main):006:0> arr.sort! { |a, b| a.to_i <=> b.to_i }
=> ["1", "2", "3", "6", "10", "20"]

irb(main):007:0> arr
=> ["1", "2", "3", "6", "10", "20"]

# パフォーマンスについてはsort_byの項目も要参照
# https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/sort_by.html
irb(main):001:0> %w[10 3 6 20 2 1].sort { |a, b| -1 }
=> ["10", "3", "6", "20", "2", "1"]

irb(main):002:0> %w[z b h a].sort { |a, b| -1 }
=> ["z", "b", "h", "a"]

# memo
# 第一引数のほうが小さいことを意味する負の整数を常に返しているのでソートされていない
irb(main):001:0> %w[z b h a].sort { |a, b| nil }
(irb):1:in `sort': comparison of String with String failed (ArgumentError)
        from (irb):1:in `<main>'
        from /Users/mfham/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/irb-1.4.1/exe/irb:11:in `<top (required)>'
        from /Users/mfham/.rbenv/versions/3.1.0/bin/irb:25:in `load'
        from /Users/mfham/.rbenv/versions/3.1.0/bin/irb:25:in `<main>'

sort_by! -> Enumerator

sort_by! {|item| ... } -> self

  • sort_byの破壊的バージョン
  • ブロックを省略した場合はEnumeratorを返す
irb(main):001:0> arr = %w[ab z car]
=> ["ab", "z", "car"]

irb(main):002:0> arr.sort_by! { |v| v.size }
=> ["z", "ab", "car"]

irb(main):003:0> arr
=> ["z", "ab", "car"]
irb(main):001:0> enum = %w[ab z car].sort_by!
=> #<Enumerator: ...>

irb(main):002:0> enum.each { |v| v.size }
=> ["z", "ab", "car"]

irb(main):003:0> enum.each { |v| -v.size }
=> ["car", "ab", "z"]