読者です 読者をやめる 読者になる 読者になる

配列同士でどちらかに所属する要素を取り出す

やりがちな書き方

a = [1, 2, 3]
b = [2, 3, 4]

c = (a + b).uniq #=> [1, 2, 3, 4]

これは集合で言うと和集合になる。RubyではArray同士の和集合を出力するメソッド | がある

https://docs.ruby-lang.org/ja/latest/class/Array.html#I_–7C

なので、元のコードは下記のように書き直せる

a = [1, 2, 3]
b = [2, 3, 4]

c = a | b #=> [1, 2, 3, 4]

ベンチマークしてみたところ、やはり直接和集合を求めたほうがわずかに早い

require 'benchmark'
a = [1,2,3,4,5]
b = [3,4,5,6,7]
n = 100000
Benchmark.bm(6, ">total:", ">avg:") do |x|
  t1 = x.report("|1:") { n.times { a | b } }
  t2 = x.report("|2:") { n.times { a | b } }
  t3 = x.report("|3:") { n.times { a | b } }

  total = t1 + t2 + t3
  [total, total/3]
end

Benchmark.bm(6, ">total:", ">avg:") do |x|
  t1 = x.report("uniq1:") { n.times { (a + b).uniq } }
  t2 = x.report("uniq2:") { n.times { (a + b).uniq } }
  t3 = x.report("uniq3:") { n.times { (a + b).uniq } }

  total = t1 + t2 + t3
  [total, total/3]
end
             user     system      total        real
|1:      0.120000   0.000000   0.120000 (  0.119706)
|2:      0.120000   0.010000   0.130000 (  0.119885)
|3:      0.110000   0.000000   0.110000 (  0.116694)
>total:  0.350000   0.010000   0.360000 (  0.356286)
>avg:    0.116667   0.003333   0.120000 (  0.118762)
             user     system      total        real
uniq1:   0.140000   0.000000   0.140000 (  0.141611)
uniq2:   0.140000   0.000000   0.140000 (  0.145371)
uniq3:   0.150000   0.000000   0.150000 (  0.144623)
>total:  0.430000   0.000000   0.430000 (  0.431605)
>avg:    0.143333   0.000000   0.143333 (  0.143868)

蛇足だが、共通項(積集合)を出力する & もある

a = [1, 2, 3]
b = [2, 3, 4]

c = a & b #=> [2, 3]