Ruby_Array_32
この記事は、以下のドキュメントを改変(自分なりに整理)して利用しています。
class Array (Ruby 3.0.0 リファレンスマニュアル)
インスタンスメソッド
intersection(*other_arrays) -> Array
- 自身と引数に渡された配列の共通要素を新しい配列として返す
- 要素が重複する場合は、そのうち1つのみを返す
- 要素の順序は自身の順序を維持する
irb(main):001:0> arr = [1, 1, 3, 5] => [1, 1, 3, 5] irb(main):002:0> brr = [3, 2, 1] => [3, 2, 1] irb(main):003:0> arr.intersection(brr) => [1, 3] irb(main):004:0> arr => [1, 1, 3, 5] irb(main):005:0> brr => [3, 2, 1] irb(main):006:0> [5, 3, 1, 1].intersection([3, 2, 1]) => [3, 1]
irb(main):001:0> [1, 2, 3, 'a', 'b', 'c'].intersection([2, 'a'], [1, 'a', 'c']) => ["a"]
iirb(main):001:0> arr = [1, 2, 3] => [1, 2, 3] irb(main):002:0> brr = arr.intersection => [1, 2, 3] irb(main):003:0> brr[1] = 'a' => "a" irb(main):004:0> arr => [1, 2, 3] irb(main):005:0> brr => [1, "a", 3] # memo # 後述の内部実装を見ても、引数がないときはforが実行されないので実質コピーしたものを返すようだ
# intersectionは内部で&の処理を順番に呼び出しているみたいだ [1] pry(main)> require 'pry-doc' => true [2] pry(main)> show-source Array#& From: array.c (C Method): Owner: Array Visibility: public Signature: &(arg1) Number of lines: 34 static VALUE rb_ary_and(VALUE ary1, VALUE ary2) { VALUE hash, ary3, v; st_data_t vv; long i; ary2 = to_ary(ary2); ary3 = rb_ary_new(); if (RARRAY_LEN(ary1) == 0 || RARRAY_LEN(ary2) == 0) return ary3; if (RARRAY_LEN(ary1) <= SMALL_ARRAY_LEN && RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) { for (i=0; i<RARRAY_LEN(ary1); i++) { v = RARRAY_AREF(ary1, i); if (!rb_ary_includes_by_eql(ary2, v)) continue; if (rb_ary_includes_by_eql(ary3, v)) continue; rb_ary_push(ary3, v); } return ary3; } hash = ary_make_hash(ary2); for (i=0; i<RARRAY_LEN(ary1); i++) { v = RARRAY_AREF(ary1, i); vv = (st_data_t)v; if (rb_hash_stlike_delete(hash, &vv, 0)) { rb_ary_push(ary3, v); } } ary_recycle_hash(hash); return ary3; } [3] pry(main)> show-source Array#intersection From: array.c (C Method): Owner: Array Visibility: public Signature: intersection(*arg1) Number of lines: 12 static VALUE rb_ary_intersection_multi(int argc, VALUE *argv, VALUE ary) { VALUE result = rb_ary_dup(ary); int i; for (i = 0; i < argc; i++) { result = rb_ary_and(result, argv[i]); } return result; }