Ruby_Array_55

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

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

インスタンスメソッド

slice(nth) -> object | nil
  • 指定された自身の要素を返す
    • Array#[]と同じ
irb(main):001:0> %w[a b c].slice(1)
=> "b"

irb(main):002:0> %w[a b c].slice(-2)
=> "b"

irb(main):003:0> %w[a b c].slice(1.0)
=> "b"

irb(main):004:0> %w[a b c].slice(10)
=> nil

irb(main):005:0> %w[a b c].slice(-5)
=> nil
irb(main):001:0> %w[a b c].slice('1')
(irb):4:in `slice': no implicit conversion of String into Integer (TypeError)
        from (irb):4: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>'
slice(pos, len) -> Array | nil
slice(range) -> Array | nil
  • 指定された自身の部分配列を返す
    • Array#[]と同じ
irb(main):001:0> %w[a b c].slice(0, 2)
=> ["a", "b"]

irb(main):002:0> %w[a b c].slice(0, 10)
=> ["a", "b", "c"]

irb(main):003:0> %w[a b c].slice(2, 1)
=> ["c"]

irb(main):004:0> %w[a b c].slice(-2, 10)
=> ["b", "c"]

# 次の二つはArray#[]でもメモしていたややこしいパターンだったはず

irb(main):005:0> %w[a b c].slice(3, 1)
=> []

irb(main):006:0> %w[a b c].slice(4, 10)
=> nil
irb(main):001:0> %w[a b c].slice(1..2)
=> ["b", "c"]

irb(main):002:0> %w[a b c].slice(3..4)
=> []

irb(main):003:0> %w[a b c].slice(4..5)
=> nil

irb(main):004:0> %w[a b c].slice(-3..-3)
=> ["a"]

irb(main):005:0> %w[a b c].slice(-3..-4)
=> []

irb(main):006:0> %w[a b c].slice(-4..-5)
=> nil
slice!(nth) -> object | nil
  • 指定した要素を自身から取り除き、取り除いた要素を返す
    • 取り除く要素がなければnilを返す
irb(main):001:0> arr = %w[a b c d e]
=> ["a", "b", "c", "d", "e"]

irb(main):002:0> arr.slice!(1)
=> "b"

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

irb(main):004:0> arr.slice!(-1)
=> "e"

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

irb(main):006:0> arr.slice!(100)
=> nil

irb(main):007:0> arr.slice!(-100)
=> nil

irb(main):008:0> arr
=> ["a", "c", "d"]
irb(main):001:0> arr = %w[a b c d e]
=> ["a", "b", "c", "d", "e"]

irb(main):002:0> arr.slice!(1.0)
=> "b"

irb(main):003:0> arr.slice!('1')
(irb):3:in `slice!': no implicit conversion of String into Integer (TypeError)
        from (irb):3: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>'  
slice!(start, len) -> Array | nil
slice!(range) -> Array | nil
  • 指定した部分配列を自身から取り除き、取り除いた部分を返す
    • 取り除く要素がなければnilを返す
irb(main):001:0> arr = %w[a b c d e]
=> ["a", "b", "c", "d", "e"]

irb(main):002:0> arr.slice!(0, 2)
=> ["a", "b"]

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

irb(main):004:0> arr.slice!(0, 100)
=> ["c", "d", "e"]

irb(main):005:0> arr
=> []
irb(main):001:0> arr = %w[a b c d e]
=> ["a", "b", "c", "d", "e"]

irb(main):002:0> arr.slice!(5, 1)
=> []

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

irb(main):004:0> arr.slice!(6, 1)
=> nil

irb(main):005:0> arr
=> ["a", "b", "c", "d", "e"]
irb(main):001:0> arr = %w[a b c d e]
=> ["a", "b", "c", "d", "e"]

irb(main):002:0> arr.slice!(2..3)
=> ["c", "d"]

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

irb(main):002:0> arr.slice!(1, 0)
=> []

irb(main):003:0> arr.slice!(1, -1)
=> nil

# memo
# 覚えておきたい
irb(main):017:0> [].slice(0, 0)
=> []

irb(main):018:0> [].slice(0, 1)
=> []

irb(main):019:0> [].slice(0, -1)
=> nil

irb(main):020:0> [].slice(1, 0)
=> nil

irb(main):021:0> [].slice(1, 1)
=> nil

irb(main):022:0> [].slice(1, -1)
=> nil


irb(main):001:0> [1].slice(1, 0)
=> []

irb(main):002:0> [1].slice(1, 1)
=> []

irb(main):003:0> [1].slice(1, -1)
=> nil

irb(main):004:0> [1].slice(2, 0)
=> nil

irb(main):005:0> [1].slice(2, 1)
=> nil

irb(main):006:0> [1].slice(2, -1)
=> nil

# memo
# 空配列に対しても考え方は同じようだ

メモ

  • slice(pos, len)とslice!(start, len)で表記揺れ

Ruby_Array_54

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

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

インスタンスメソッド

shuffle -> Array
shuffle(random: Random) -> Array
  • 配列の要素をランダムシャッフルし、その結果を配列として返す
  • 引数にRandomオブジェクトを渡すことでそのオブジェクトが生成する擬似乱数列を用いることができる
irb(main):001:0> arr = %w[a b c d e]
=> ["a", "b", "c", "d", "e"]

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

irb(main):003:0> arr.shuffle
=> ["d", "e", "b", "a", "c"]
irb(main):001:1* class Foo
irb(main):002:2*   def self.rand(arg)
irb(main):003:2*     0.1
irb(main):004:1*   end
irb(main):005:0> end
=> :rand

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

irb(main):007:0> arr.shuffle(random: Foo)
=> ["b", "c", "d", "e", "a"]

irb(main):008:0> arr.shuffle(random: Foo)
=> ["b", "c", "d", "e", "a"]

irb(main):009:0> arr.shuffle(random: Foo)
=> ["b", "c", "d", "e", "a"]
shuffle! -> self
shuffle!(random: Random) -> self
  • 配列を破壊的にランダムシャッフルする
  • randomには乱数生成器(主にRandomオブジェクト)を指定する
    • 選択する要素のインデックスを返す rand メソッドに応答するオブジェクトであれば指定することが可能
    • randメソッドの引数にはRandom#rand(max) のように選択可能なインデックスの最大値が指定される
    • Kernel.#rand、Random を使用しないオブジェクトを指定した場合、Kernel.#srandの指定に影響されない
    • Ruby_Array_52 - にっちとだじゃれ に書いたsampleメソッド時の挙動と違う?バグ?
irb(main):001:0> arr = %w[a b c d e]
=> ["a", "b", "c", "d", "e"]

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

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

irb(main):012:0> arr.shuffle!(random: Foo)
=> ["b", "c", "d", "e", "a"]

irb(main):013:0> arr.shuffle!(random: Bar)
<internal:array>:13:in `shuffle!': random number too big 2 (RangeError)
        from (irb):13: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>' 

# ちなみにrandomメソッドに対して同クラスを指定すると次のようにエラーは起きない
# randomに関するドキュメントの説明文は同じなのに何で・・・?
# 「選択する要素のインデックスを返す rand メソッドに応答するオブジェクトであれば」をrandメソッドがインデックスを返せば(整数)良いと理解したけど・・・

irb(main):014:0> arr.sample(random: Foo)
=> "b"

irb(main):015:0> arr.sample(random: Bar)
=> "e"

Ruby_Array_53

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

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

インスタンスメソッド

shift -> object | nil
shift(n) -> Array
  • 配列の先頭の要素を取り除いてそれを返す
    • 引数を指定した場合、その個数だけ取り除きそれを配列で返す
    • nが自身の要素より大きい場合はその要素数の配列を返す
      • ドキュメントでは「少ない場合は」って書いてあるけど、意味合い的に間違いのような気がする?
      • その場合、自身は空配列となる
  • 空配列の場合、nが指定されていない場合はnilを、指定されている場合は空配列を返す
    • 覚えておきたい
  • 引数に整数以外の(暗黙の型変換が行えない)オブジェクトを指定した場合TypeErrorが、負の数を指定した場合ArgumentErrorが発生する
irb(main):001:0> arr = %w[a b c d e]
=> ["a", "b", "c", "d", "e"]

irb(main):002:0> arr.shift
=> "a"

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

irb(main):004:0> arr.shift(2)
=> ["b", "c"]

irb(main):005:0> arr
=> ["d", "e"]

irb(main):006:0> arr.shift(10)
=> ["d", "e"]

irb(main):007:0> arr
=> []
irb(main):001:0> [].shift
=> nil

irb(main):002:0> [].shift(5)
=> []

# memo
# この挙動の違いは覚えておきたい
irb(main):001:0> [].shift(1.0)
=> []

irb(main):002:0> [].shift('1')
(irb):2:in `shift': no implicit conversion of String into Integer (TypeError)
        from (irb):2: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>'

irb(main):003:0> [].shift(-1)
(irb):3:in `shift': negative array size (ArgumentError)
        from (irb):3: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>'

メモ

  • 今回から実行環境をRuby3.1.0にします

Ruby_Array_52

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

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

インスタンスメソッド

sample -> object | nil
sample(n) -> Array
sample(random: Random) -> object | nil
sample(n, random: Random) -> Array
  • 配列の要素1個ランダムに選んで返す
    • 引数を指定した場合は自身の要素数を超えない範囲でn個ランダムに選んで返す
  • 重複したインデックスは選択されない
    • そのため、自身がユニークな配列の場合は返り値もユニークな配列になる
  • 配列が空の場合、無引数の場合はnilを、個数を指定した場合は空配列を返す
  • srand()が有効
  • nに自身の要素数以上の値を指定した場合、要素数と同じ数の配列を返す
  • randomには乱数生成器(主にRandomオブジェクト)を指定する
    • 選択する要素のインデックスを返す rand メソッドに応答するオブジェクトであれば指定することが可能
    • randメソッドの引数にはRandom#rand(max) のように選択可能なインデックスの最大値が指定される
    • Kernel.#rand、Random を使用しないオブジェクトを指定した場合、Kernel.#srandの指定に影響されない
  • nに整数以外の(暗黙の型変換が行えない)オブジェクトを指定した場合TypeErrorが、負の数を指定した場合ArgumentErrorが発生する
irb(main):001:0> arr = [1, 'a', ['A', 'B']]
=> [1, "a", ["A", "B"]]

irb(main):002:0> arr.sample
=> 1
...
irb(main):005:0> arr.sample
=> ["A", "B"]
...
irb(main):016:0> arr.sample
=> "a"
...
irb(main):018:0> arr.sample(2)
=> [["A", "B"], 1]

irb(main):019:0> arr.sample(2)
=> ["a", ["A", "B"]]

irb(main):020:0> arr.sample(2)
=> ["a", 1]
irb(main):001:1* class Foo
irb(main):002:2*   def self.rand(arg)
irb(main):003:2*     pp arg
irb(main):004:2*     1
irb(main):005:1*   end
irb(main):006:1* end
=> :rand
irb(main):007:0> %w[a b c d e].sample(random: Foo)
5
=> "b"
irb(main):008:0> %w[a b c d e].sample(random: Foo)
5
=> "b"
irb(main):009:0> %w[a b c d e].sample(random: Foo)
5
=> "b"

irb(main):010:0> %w[a b c d e].sample(3, random: Foo)
5
4
3
=> ["b", "c", "d"]
irb(main):011:0> %w[a b c d e].sample(3, random: Foo)
5
4
3
=> ["b", "c", "d"]
irb(main):012:0> %w[a b c d e].sample(3, random: Foo)
5
4
3
=> ["b", "c", "d"]
irb(main):001:0> %w[a b c d e].sample(1.0)
=> ["a"]

irb(main):002:0> %w[a b c d e].sample('1')
<internal:array>:66:in `sample': no implicit conversion of String into Integer (TypeError)
        from (irb):2: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>' 

irb(main):003:0> %w[a b c d e].sample(-1)
<internal:array>:66:in `sample': negative sample number (ArgumentError)
        from (irb):3: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>' 

メモ

Ruby_Array_51

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

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

インスタンスメソッド

rotate(cnt = 1) -> Array
  • cntで指定したインデックスの要素が先頭になる配列を新しく生成する
    • 負の数を指定した場合、逆の操作を行う
    • 指定しなかった場合、cntは1になる
    • 整数以外の(暗黙の型変換が行えない)オブジェクトを指定した場合はTypeErrorが発生する
irb(main):001:0> arr = %w[a b c d e]
=> ["a", "b", "c", "d", "e"]

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

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

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

irb(main):005:0> arr.rotate(4)
=> ["e", "a", "b", "c", "d"]

irb(main):006:0> arr.rotate(5)
=> ["a", "b", "c", "d", "e"]

irb(main):007:0> arr.rotate(-2)
=> ["d", "e", "a", "b", "c"]
irb(main):001:0> %w[a b c d e].rotate(1.0)
=> ["b", "c", "d", "e", "a"]

irb(main):002:0> %w[a b c d e].rotate('1')
Traceback (most recent call last):
        5: from /Users/mfham/.rbenv/versions/3.0.0/bin/irb:23:in `<main>'
        4: from /Users/mfham/.rbenv/versions/3.0.0/bin/irb:23:in `load'
        3: from /Users/mfham/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/irb-1.3.0/exe/irb:11:in `<top (required)>'
        2: from (irb):2:in `<main>'
        1: from (irb):2:in `rotate'
TypeError (no implicit conversion of String into Integer)
rotate!(cnt = 1) -> self
  • cntで指定したインデックスの要素が先頭になるように自身の順番を変更する
    • 負の数を指定した場合、逆の操作を行う
    • 指定しなかった場合、cntは1になる
    • 整数以外の(暗黙の型変換が行えない)オブジェクトを指定した場合はTypeErrorが発生する
irb(main):001:0> arr = %w[a b c d e]
=> ["a", "b", "c", "d", "e"]

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

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

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

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

irb(main):006:0> arr.rotate!(-2)
=> ["c", "d", "e", "a", "b"]

irb(main):007:0> arr
=> ["c", "d", "e", "a", "b"]
irb(main):008:0> 
irb(main):001:0> %w[a b c d e].rotate!(1.0)
=> ["b", "c", "d", "e", "a"]

irb(main):002:0> %w[a b c d e].rotate!('1')
Traceback (most recent call last):
        5: from /Users/mfham/.rbenv/versions/3.0.0/bin/irb:23:in `<main>'
        4: from /Users/mfham/.rbenv/versions/3.0.0/bin/irb:23:in `load'
        3: from /Users/mfham/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/irb-1.3.0/exe/irb:11:in `<top (required)>'
        2: from (irb):2:in `<main>'
        1: from (irb):2:in `rotate!'
TypeError (no implicit conversion of String into Integer)

Ruby_Array_50

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

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

インスタンスメソッド

rindex(val) -> Integer | nil
rindex {|item| ... } -> Integer | nil
rindex -> Enumerator
  • 指定されたvalと==で等しい最後の要素の位置を返す
    • 等しい要素がひとつもなかった場合はnilを返す
  • ブロックが与えられた場合、各要素を末尾から順に引数としてブロックを実行し、ブロックが真を返す最初の要素の位置を返す
    • ブロックが真を返す要素がなかったときはnilを返す
  • 引数、ブロックのどちらも与えられなかった場合、自身とrindexから生成したEnumeratorオブジェクトを返す
irb(main):001:0> arr = ['a', 'b', 'a', nil]
=> ["a", "b", "a", nil]

irb(main):002:0> arr.rindex('b')
=> 1

irb(main):003:0> arr.rindex('a')
=> 2

irb(main):004:0> arr.rindex(nil)
=> 3

irb(main):005:0> arr.rindex('z')
=> nil
irb(main):001:0> [1, 2].rindex(1.0)
=> 0

irb(main):002:0> [1, 2].rindex('1')
=> nil

irb(main):003:0> [1.0, 2].rindex('1')
=> nil
irb(main):001:0> [1, 3, 5, 7].rindex { |v| v > 4 }
=> 3
irb(main):001:0> arr = [1, 5, 7, 3]
=> [1, 5, 7, 3]

irb(main):002:0> enum = arr.rindex
=> #<Enumerator: [1, 5, 7, 3]:rindex>

irb(main):003:0> enum.each { |v| puts v }
3
7
5
1
=> nil

irb(main):004:0> enum.each { |v| v > 4 }
=> 2

irb(main):005:0> enum.each { |v| v < 0 }
=> nil

irb(main):006:0> arr << 6
=> [1, 5, 7, 3, 6]

irb(main):007:0> enum
=> #<Enumerator: [1, 5, 7, 3, 6]:rindex>

Ruby_Array_49

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

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

インスタンスメソッド

reverse -> Array
reverse! -> self
  • 自身の要素を逆順に並べた新しい配列を生成して返す
  • reverse!は自身を破壊的に並べ替え、selfを返す
irb(main):001:0> arr = ['a', 1, 5]
=> ["a", 1, 5]

irb(main):002:0> brr = arr.reverse
=> [5, 1, "a"]

irb(main):003:0> brr
=> [5, 1, "a"]

irb(main):004:0> arr[0].capitalize!
=> "A"

irb(main):005:0> arr
=> ["A", 1, 5]

irb(main):006:0> brr
=> [5, 1, "A"]
irb(main):001:0> arr = ['a', 1, 5]
=> ["a", 1, 5]

irb(main):002:0> arr.reverse!
=> [5, 1, "a"]

irb(main):003:0> arr
=> [5, 1, "a"]
reverse_each {|item| ... } -> self
reverse_each -> Enumerator
  • 各要素に対して逆順にブロックを評価する
  • ブロックが与えられなかった場合、自身と reverse_each から生成した Enumeratorオブジェクトを返す
irb(main):001:0> arr = %w[a b c]
=> ["a", "b", "c"]

irb(main):002:0> arr.reverse_each { |v| puts v.capitalize }
C
B
A
=> ["a", "b", "c"]

irb(main):003:0> arr
=> ["a", "b", "c"]
irb(main):001:0> arr = %w[a b c]
=> ["a", "b", "c"]

irb(main):002:0> arr.reverse_each { |v| puts v.capitalize! }
C
B
A
=> ["A", "B", "C"]

irb(main):003:0> arr
=> ["A", "B", "C"]
irb(main):001:0> arr = %w[a b c]
=> ["a", "b", "c"]

irb(main):002:0> enum = arr.reverse_each
=> #<Enumerator: ["a", "b", "c"]:reverse_each>

irb(main):003:0> enum.each { |v| puts v }
c
b
a
=> ["a", "b", "c"]

irb(main):004:0> arr[1].capitalize!
=> "B"

irb(main):005:0> enum
=> #<Enumerator: ["a", "B", "c"]:reverse_each>

irb(main):006:0> enum.each { |v| puts v }
c
B
a
=> ["a", "B", "c"]