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
とかでもいいかも - 要素数が違う場合は、大きい方の要素数の配列が得られる
-
result
とa1
の参照先が同じになるので、a1
の内容も変化してしまう。 -
a1
の値を変更したくなければ、sum = a1.clone
でa1
の値をコピーしておき、each_with_object
にはsum
を渡す - ちょっと無理矢理感が出ている気がする
もっとエレガントな書き方は無いものか…。
(追記)
コメント欄にて、もっといい方法をご教授いただきました。
ぜひコメント欄もご覧ください。