Enumerable#map_with_index が欲しい……かも?
同じ size の複数の Array を操作するようなプログラムを書いているときに、ふと map_with_index メソッドが欲しいなあ、と思った。*1
たとえば、下のような感じ。
module Enumerable def map_with_index n = -1 map {|x| yield(x, n += 1)} end end result = a.map_with_index {|x, i| x.method(b[i], c[i]) }
もし map_with_index を使わずに同様のことをやろうとしたら、下のような感じかな。
# (1) result = (0...a.size).map {|i| a[i].method(b[i], c[i]) } # (2) result = a.zip(b, c).map {|v| v[0].method(v[1], v[2]) } # (3) result = [a, b, c].transpose.map {|v| v[0].method(v[1], v[2]) }
(1)は、いきなり Range が出てくるのが馬鹿っぽいし見た目に冗長だが、分かりやすい。
(2), (3) は、v[0] や v[1] という表記の 0 や 1 がマジックナンバーっぽく見えて気になる。まあ、ブロックの冒頭で "aa, bb, cc = *v" とか代入すればいいんだけど。
(3) は、a, b, c の size が違ったときに transpose で例外が起こる。例外が望ましいかどうかは状況によるが、望ましい場合が多い気もする。
……と、ここまで考えて、そもそも「同じ size の Array が複数あって、それらを組にして扱っている」というのはデータの持ち方を間違えているような気がしてきた。新しくクラスを作って、それの Array にできるんじゃないのか?
とりあえずの結論。map_with_index が欲しくなる状況というのは、そもそもデータの持ち方を間違えている可能性が高い。
*1:Google で検索 してみたら、同じようなことを考えてる人はそれなりにいるらしい。