Ruby_Array_17

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

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

インスタンスメソッド

delete(val) -> object | nil
delete(val) { ... } -> object
  • 指定したvalと==で等しい要素を自身からすべて取り除く
    • 等しい要素が見つかった場合は最後に見つかった要素を、そうでない場合はnilを返す
  • ブロックが与えられた場合、valと等しい要素が見つからなかったときにブロックを評価してその結果を返す
irb(main):001:0> arr = %w[a b c a b]
=> ["a", "b", "c", "a", "b"]

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

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

irb(main):002:0> arr.delete(nil)
=> nil

irb(main):003:0> arr
=> []

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

# memo
# ブロックなしの引数に nil を渡すとその戻り値から削除が行われたかどうかの判定をすることはできない
# -> 要素が見つかったときもnilが返されるし、見つからなかった場合もnilが返されるため
irb(main):001:0> arr = [1, 2, 3]
=> [1, 2, 3]

irb(main):002:0> arr.delete(4) { puts 'not found' }
not found
=> nil

irb(main):003:0> arr
=> [1, 2, 3]

irb(main):004:0> arr.delete(3) { puts 'not found' }
=> 3

irb(main):005:0> arr
=> [1, 2]
irb(main):001:0> a = 'foo'
=> "foo"

irb(main):002:0> b = 'foo'
=> "foo"

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

irb(main):004:0> v = arr.delete('foo')
=> "foo"

irb(main):005:0> v << 'bar'
=> "foobar"

irb(main):006:0> a
=> "foo"

irb(main):007:0> b
=> "foobar"

irb(main):008:0> arr
=> []

# memo
# "最後に見つかった要素"を返すことの確認ができた。なるほど。
delete_at(pos) -> object | nil
  • 指定された位置posにある要素を取り除き、それを返す
    • posが範囲外であったらnilを返す
    • 負のインデックスで末尾から指定することも可能
irb(main):001:0> arr = [1, 2, 3]
=> [1, 2, 3]

irb(main):002:0> arr.delete_at(1)
=> 2

irb(main):003:0> arr
=> [1, 3]
irb(main):001:0> arr = [1, 2, 3]
=> [1, 2, 3]
irb(main):002:0> arr.delete_at(-1)
=> 3
irb(main):003:0> arr
=> [1, 2]
irb(main):001:0> arr = [1, 2, 3]
=> [1, 2, 3]

irb(main):002:0> arr.delete_at(10)
=> nil

irb(main):003:0> arr
=> [1, 2, 3]
delete_if {|x| ... } -> self
reject! {|x| ... } -> self | nil
delete_if -> Enumerator
reject! -> Enumerator
  • 要素を順番にブロックに渡して評価し、その結果が真になった要素をすべて削除する
  • delete_ifは常にselfを返す
  • reject!は要素が1つ以上削除されればselfを、そうでなければnilを返す
  • ブロックが与えられなかった場合は、Enumeratorオブジェクトを返す
    • 返されたEnumeratorのeachメソッドには、もとの配列に対して副作用があることに注意
irb(main):001:0> arr = [1, 2, 3, 4, 5]
=> [1, 2, 3, 4, 5]

irb(main):002:0> arr.delete_if {|v| v % 2 == 0 }
=> [1, 3, 5]

irb(main):003:0> arr
=> [1, 3, 5]

irb(main):004:0> arr.delete_if {|v| v == 10 }
=> [1, 3, 5]

irb(main):005:0> arr
=> [1, 3, 5]
irb(main):001:0> arr = [1, 2, 3, 4, 5]
=> [1, 2, 3, 4, 5]

irb(main):002:0> arr.reject! {|v| v % 2 == 0 }
=> [1, 3, 5]

irb(main):003:0> arr
=> [1, 3, 5]

irb(main):004:0> arr.reject! {|v| v == 10 }
=> nil

irb(main):005:0> arr
=> [1, 3, 5]
irb(main):001:0> arr = [1, 2, 3, 4, 5]
=> [1, 2, 3, 4, 5]

irb(main):002:0> v = arr.delete_if
=> #<Enumerator: [1, 2, 3, 4, 5]:delete_if>

irb(main):003:0> v
=> #<Enumerator: [1, 2, 3, 4, 5]:delete_if>

irb(main):004:0> v.each {|v| v % 2 == 0 }
=> [1, 3, 5]

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

irb(main):006:0> v.each {|v| v == 10 }
=> [1, 3, 5]

irb(main):007:0> arr
=> [1, 3, 5]
irb(main):001:0> arr = [1, 2, 3, 4, 5]
=> [1, 2, 3, 4, 5]

irb(main):002:0> v = arr.reject!
=> #<Enumerator: [1, 2, 3, 4, 5]:reject!>

irb(main):003:0> v
=> #<Enumerator: [1, 2, 3, 4, 5]:reject!>

irb(main):004:0> v.each {|v| v % 2 == 0 }
=> [1, 3, 5]

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

irb(main):006:0> v.each {|v| v == 10 }
=> nil

irb(main):007:0> arr
=> [1, 3, 5]

メモ

  • deleteにブロックを与えられることを今知った
  • delete_ifとreject!の違いは覚えておきたい