zipWithの自作
id:omochistさんのzipWithを読んで、私も書いてみました。。
対称的じゃないので、きれいじゃないけど、dupしないというメリットはあります。
def zipWith(xs, ys, &block) zipped = [] xs.each_with_index do |x, k| zipped << block.call(x, ys[k]) end zipped end a = (1..5).to_a b = (3..7).to_a p zipWith(a, b) { |x, y| x + y } #=> [4, 6, 8, 10, 12]
追記:omochistさんから、ysのほうが短いとエラーという指摘がありました。確かに。
追記:通りすがりさんから、Enumerable#zipがあるよと教えていただきました。確かに。
では、zipを使って、さらに複数個のzip_withもできるように。この場合、長さにずれがあると開いたところにはnilが入ってブロックに渡されます。
module Enumerable def zip_with(*es, &block) zipped = [] zip(*es) do |args| zipped << block.call(*args) end zipped end end a = (1..5).to_a b = (3..7).to_a c = (101..105).to_a p a.zip_with(b, c) { |x, y, z| x + y + z } #=> [105, 108, 111, 114, 117]
追記:すでに同様のコードをsumimさんが書かれていました…。
追記:passerbyさんから。mapか…。みなさんありがとうございます♪
module Enumerable def zip_with(*others, &block) zip(*others).map &block end end p (1..5).zip_with(3..7) {|a,b| a+b} #=> [4, 6, 8, 10, 12]
追記:ttateさんから。