はじめに
Rails 6 に追加されそうな新機能を試す第14段。 今回のちょい足し機能は、 Array#extract!
編です。
Arrayから条件を満足する要素を取り除いて取り除かれた要素を配列として返す extract! メソッドが追加されました。
言葉で説明するとややこしいです。実際に試すとわかりやすいです。
記載時点では、Rails は 6.0.0.rc1 です。 gem install rails --prerelease
でインストールできます。
$ rails --version
Rails 6.0.0.rc1
Ruby は、2.6.3 です。
$ ruby -v
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux-musl]
irb を実行
ActiveSupport で追加されている機能なので、irb で試すことにします。
$ irb -ractive_support/core_ext
irb(main):001:0> ary = [1, 2, 3, 4, 5]
=> [1, 2, 3, 4, 5]
irb(main):002:0> even = ary.extract!{ |i| i.even? }
=> [2, 4]
irb(main):003:0> even
=> [2, 4]
irb(main):004:0> ary
=> [1, 3, 5] # <= 元の配列から偶数は取り除かれる!
ここで、注意したいポイントは、 Array#extract!
を実行すると元の配列 ( ary
) も変わってしまうということです。
(メソッドの名前の最後に !
がついていることから、元の配列を変えてしまういわゆる「破壊的メソッド」であることが想像できます。)
Array#select (Array#filter) との違い
Array#select
( Array#filter
) は、ブロックの評価が真となる要素の配列を返しますが、元の配列は変わりません。
irb(main):008:0> ary = [1, 2, 3, 4, 5]
=> [1, 2, 3, 4, 5]
irb(main):009:0> even = ary.select{ |i| i.even? }
=> [2, 4]
irb(main):010:0> even
=> [2, 4]
irb(main):011:0> ary
=> [1, 2, 3, 4, 5] # <= 元の配列は変わらない。
Array#select!
( Array#filter!
) との違い
Array#select!
( Array#filter!
) は、ブロックの評価が真となる要素の配列を返しますが、元の配列が返される配列と同じになります。
irb(main):012:0> ary = [1, 2, 3, 4, 5]
=> [1, 2, 3, 4, 5]
irb(main):013:0> even = ary.select!{ |i| i.even? }
=> [2, 4]
irb(main):014:0> ary
=> [2, 4] # <= 元の配列は変わる
irb(main):015:0> even.__id__ == ary.__id__
=> true # <= even と ary は同じもの
Enumerable#Partition Array#partition との違い
Enumerable#partition は、ブロックの評価が真となる要素の配列と偽となる要素の配列を返しますが、元の配列は変わりません。Array#partition
irb(main):004:0> ary = [1, 2, 3, 4, 5]
=> [1, 2, 3, 4, 5]
irb(main):005:0> even, odd = ary.partition{ |i| i.even? }
=> [[2, 4], [1, 3, 5]]
irb(main):006:0> even
=> [2, 4]
irb(main):007:0> odd
=> [1, 3, 5]
irb(main):008:0> ary
=> [1, 2, 3, 4, 5]