Ruby
Rails
Rails6

Rails6 のちょい足しな新機能を試す14(Array#extract!編)


はじめに

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]


参考情報