Just do IT

思うは招く

Ruby基礎問題100本ノック#15 複数の配列に並行してアクセスする

お題

  • 数値からなる配列num1とnum2にたいして、それらの個々の要素を足し合わせた要素からなる配列を返すメソッドsum_arrayを定義せよ

こんな感じの結果にせよ。

p sum_array([1, 2, 3],[4, 6, 8]) 
=> [5, 8, 11]

(たのしいRubyに収録されている例題です)

回答

num1 = [1,2,3]
num2 = [4,6,8]

def sum_array(ary1, ary2)
  result = []
  ary1.zip(ary2) do |a, b|
    result << a + b
  end
  result # return の意味で
end
p sum_array(num1, num2)

説明

まずは、計算に使う配列を2つ作る。

num1 = [1,2,3]
num2 = [4,6,8]

zipメソッドを使うと、複数の配列の同じインデックスの要素に並列にアクセスできる。

ary1.zip(ary2) do |a, b|
    result << a + b
  end

この場合、aにはary1の要素が入り、bにはary2の要素が入る。2つの値はそれぞれ同じインデックスから取得されている。

よって、処理を細かく追ってみるとこうなる。

p result << a + b
=> 
[5]
[5, 8]
[5, 8, 11]

最後に、ブロックを抜けたあとにreturnの意味で作った配列resultを書いておく。これを書かないと、nilが返ってくる。

return result

と書いてもいいが、チェリー本によるとRubyではreturnをしたいときでもreturnは書かないのが主流。なぜなら、Rubyでは最後に評価された式がメソッドの戻り値になるから。他の言語から入るとちょっと戸惑うが、すぐに慣れる。

回答

def sum_array(ary1, ary2)
  result = []
  ary1.zip(ary2) do |a, b|
    result << a + b
  end
  result # return の意味で
end

学び

result配列はArray.newメソッドでも作れる。

# どちらも同じ意味
result = []
result = Array.new

zipメソッドを使わずに書く。

num1 = [1,2,3]
num2 = [4,6,8]

def sum_array_each(ary1, ary2)
  result = []
  i = 0
  ary1.each do |n|
    result << n + ary2[i]
    i += 1
  end
  result
end
p sum_array_each(num1, num2)

自分でary2のためにインデックスiを作ってあげて、1回の処理が終わった後に1を足し、ary1の要素nに合わせている。

こう見ると、zipメソッドの便利さがわかる。 zipメソッドはあまり使ったことがなかったが、この機会に触れることができてよかった。