読者です 読者をやめる 読者になる 読者になる
無料で使えるシステムトレードフレームワーク「Jiji」 をリリースしました!

・OANDA Trade APIを利用した、オープンソースのシステムトレードフレームワークです。
・自分だけの取引アルゴリズムで、誰でも、いますぐ、かんたんに、自動取引を開始できます。

Enumerable#mapの途中でindexにアクセスしたい

Ruby

次のようなEnumerableをincludeしたクラスがあって、

class Foo
  include Enumerable
  def each
    ["a","b","c"].each{|i| yield i } # もちろんこんな実装じゃないよ
  end
end

これのEnumerable#mapのブロック中で、現在の要素のインデックスが必要になったので、↓こうしてみた。

class Foo
  include Enumerable
  def each
    $index = 0
    ["a","b","c"].each{|i| 
      yield i
      $index += 1
    }
  end
end

これで「$index」で現在の要素のインデックスにアクセスできるようになる。mapだけでなくinjectとかでももちろん使える。

f = Foo.new

puts "---map"
puts f.map{|i| "#{$index}:#{i}" }.join("\n")

puts "---each"
f.each{|i| puts "#{$index}:#{i}"  }

puts "---inject"
puts f.inject(""){|r,i| r << "#{$index}:#{i}\n" }

実行結果です。

---map
0:a
1:b
2:c
---each
0:a
1:b
2:c
---inject
0:a
1:b
2:c

ただし、グローバル変数なので、複数スレッドで使う場合に不整合になりやすい。注意。あと、イテレート中にイテレートとかしてもまずい。・・・やっぱ微妙だなー。↓こんなんの方がましかなー。

j=-1;puts f.map{|i| "#{j+=1}:#{i}" }.join("\n")