Ruby_Array_34
この記事は、以下のドキュメントを改変(自分なりに整理)して利用しています。
class Array (Ruby 3.1 リファレンスマニュアル)
インスタンスメソッド
keep_if {|item| ... } -> self
keep_if -> Enumerator
- ブロックがfalseを返した要素を削除する
- Array#select!と同様に自身を上書きするが、削除する要素がなかった場合には修正を行わない
- ブロックが与えられなかった場合、自身とkeep_ifから生成したEnumeratorオブジェクトを返す
irb(main):001:0] arr = %w[a b c d e] => ["a", "b", "c", "d", "e"] irb(main):003:0> arr.keep_if {|s|s =~ /[ace]/ } => ["a", "c", "e"] irb(main):004:0> arr => ["a", "c", "e"]
irb(main):001:0> arr = %w[a b c d e] => ["a", "b", "c", "d", "e"] irb(main):002:0> arr.keep_if {|s|s =~ /[z]/ } => [] irb(main):003:0> arr => []
irb(main):001:0> arr = %w[a b c d e] => ["a", "b", "c", "d", "e"] irb(main):002:0> arr.keep_if {|s| s =~ /[a-z]/ } => ["a", "b", "c", "d", "e"] irb(main):003:0> arr => ["a", "b", "c", "d", "e"] # Array#select!は削除する要素がなかったときにnilを返す。ここが違うところ。 irb(main):004:0> brr = %w[a b c d e] => ["a", "b", "c", "d", "e"] irb(main):005:0> brr.select! {|s| s =~ /[a-z]/ } => nil irb(main):006:0> brr => ["a", "b", "c", "d", "e"]
# Array#select!はArray#keep_ifの処理に加えて他の処理もしている [1] pry(main)> require 'pry-doc' => true [2] pry(main)> show-source Array#keep_if From: array.c (C Method): Owner: Array Visibility: public Signature: keep_if() Number of lines: 7 static VALUE rb_ary_keep_if(VALUE ary) { RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length); rb_ary_select_bang(ary); return ary; } [3] pry(main)> show-source Array#select! From: array.c (C Method): Owner: Array Visibility: public Signature: select!() Number of lines: 12 static VALUE rb_ary_select_bang(VALUE ary) { struct select_bang_arg args; RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length); rb_ary_modify(ary); args.ary = ary; args.len[0] = args.len[1] = 0; return rb_ensure(select_bang_i, (VALUE)&args, select_bang_ensure, (VALUE)&args); }
irb(main):001:0> arr = %w[a b c d e] => ["a", "b", "c", "d", "e"] irb(main):002:0> enum = arr.keep_if => #<Enumerator: ["a", "b", "c", "d", "e"]:keep_if> irb(main):003:0> arr[4] = 'z' => "z" irb(main):004:0> enum => #<Enumerator: ["a", "b", "c", "d", "z"]:keep_if> irb(main):005:0> enum.each {|s| s =~ /[acz]/ } => ["a", "c", "z"] irb(main):006:0> enum => #<Enumerator: ["a", "c", "z"]:keep_if>