JavaScriptではforEach()などのループにthisが渡される。要素の番号も一緒にわたってくる。
var a = [6, 5, 4]; a.map(function (elm) { return elm * 2; }). forEach(function (elm, i, a) { console.log([elm, i, a]); }); // [ 12, 0, [ 12, 10, 8 ] ] // [ 10, 1, [ 12, 10, 8 ] ] // [ 8, 2, [ 12, 10, 8 ] ]
Rubyのeachはそんな引数はくれない。そこでeach_with_indexとクロージャを組み合はせることをする。
a = [6, 5, 4] a2 = a.map{|elm| elm * 2 } a2.each_with_index{|elm, i| p [elm, i, a2] } # [12, 0, [12, 10, 8]] # [10, 1, [12, 10, 8]] # [8, 2, [12, 10, 8]]
変数は偉大だ。
RubyにはEnumerable#each_with_index, with_index, each_with_object, with_objectといふメソッドがある。each_with_selfといふのは無い。そこで一時変数を使ひたくない病に罹れば、tap breakをつかふ。
a = [6, 5, 4] a.map{|elm| elm * 2 }. tap{|a| break a.map{|elm| [elm, a] } }. each_with_index. map{|elma, i| [elma[0], i, elma[1]] }. each{|elm, i, a| p [elm, i, a] }
Object#tapにbreakを入れて、tapの返り値を得てゐる。誰がこんなことやるか。
このたいへんな見た目を隠す為に、Array#each_with_selfとArray#each_with_index_and_selfといふメソッドを作ってみる。
class Array def each_with_self &block enum = map{|elm| [elm, self] } return enum unless block enum.each &block end def each_with_index_and_self &block enum = each_with_self. each_with_index. map{|elma, i| [elma[0], i, elma[1]] } return enum unless block enum.each &block end end module Enumerable def each_with_self &block enum = map{|elm| [elm, self] } return enum unless block enum.each &block end def each_with_index_and_self &block enum = each_with_self. each_with_index. map{|elma, i| [elma[0], i, elma[1]] } return enum unless block enum.each &block end end a = [6, 5, 4] a.map{|elm| elm * 2 }. each_with_index_and_self{|elm, i, a| p [elm, i, a] }
一時変数をつかへばいいとおもふ。