30
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Rubyで配列をベクトル的に足し算したい

Last updated at Posted at 2014-08-14

Rubyの配列には、ベクトルのように要素同士を足し合わせるようなメソッドが用意されていない。
普通に足し算すると配列の連結になってしまうし…。
格好を気にしなければいくらでもやり方はあるけれど、できるだけいい感じに書きたい!

Vectorクラスを使う

a1  = [1, 2, 3]
a2  = [4, 5, 6]

sum = (Vector.elements(a1) + Vector.elements(a2)).to_a
  • 要素数が違うものは足し合わせられない
  • 要素はNumericクラスのみ
  • (追記)コメント欄、Nabetani様より。Numericでなくても一応それらしく動くとのことです。

外部イテレータを使う

a1 = [1, 2, 3]
a2 = [4, 5, 6]

e1 = a1.to_enum
e2 = a2.to_enum

sum = []
loop do
  sum << e1.next + e2.next 
end
  • Numericクラス以外(文字列とか)でも使える
  • 要素数が違う場合は、小さい方の要素数の配列しか得られない

Enumerable#each_with_objectを使う

a1 = [1, 2, 3]
a2 = [4, 5, 6]

sum = a2.each_with_object(a1).with_index(0){ |(elm, result), idx|
  result[idx]  = result[idx].to_i +  elm
}
  • Numericクラス以外(文字列とか)でも使える
  • ただし、result[idx].to_iの部分はクラスによって要変更(result[idx]nilのとき対策)
  • result[idx] || 0とかでもいいかも
  • 要素数が違う場合は、大きい方の要素数の配列が得られる
  • resulta1の参照先が同じになるので、a1の内容も変化してしまう。
  • a1の値を変更したくなければ、sum = a1.clonea1の値をコピーしておき、each_with_objectにはsumを渡す
  • ちょっと無理矢理感が出ている気がする

もっとエレガントな書き方は無いものか…。

(追記)
コメント欄にて、もっといい方法をご教授いただきました。
ぜひコメント欄もご覧ください。

30
24
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?