From: Logan Capaldo Date: 2005-05-26T01:24:28+09:00 Subject: Re: loop over array with indices On 5/24/05, Brian Schr�der wrote: > On 23/05/05, Berger, Daniel wrote: > > > -----Original Message----- > > > From: Johannes Ahlmann [mailto:softpro@gmx.net] > > > Sent: Monday, May 23, 2005 3:15 PM > > > To: ruby-talk ML > > > Subject: loop over array with indices > > > > > > > > > hi, > > > > > > i have the recurring problem that i want to loop over an > > > array with each/collect/... but (as an afterthought) need the > > > index of the current element. > > > > See Enumerable#each_with_index. > > > > Regards, > > > > Dan > > > > > > And define yourself map_with_index, inject_with_index etc. where > needed. I always miss them. > > best regards, > > Brian > > > -- > http://ruby.brian-schroeder.de/ > > Stringed instrument chords: http://chordlist.brian-schroeder.de/ > > require 'enumerator' arr = [ "a", "b", "c", "d" ] arr_iter = Enumerable::Enumerator.new(arr, :each_with_index) arr_iter.each do |x, i| puts "arr[#{i}] => #{x}" end #=> arr[0] => a arr[1] => b arr[2] => c arr[3] => d arr_iter.collect { |x, i| x[0] + i } #=> [97, 99, 101, 103] etc. Any methods defined in enumerable should work including each, map, inject, etc. inject's args may look a little weird depending on how you call it ie: arr_iter.inject("q") { |a, b| a << b[0] << b[1].to_s } #=> "qa0b1c2d3" arr_iter.inject { |a, b| (a.kind_of?(Array) ? a[0] + a[1].to_s : a) + b[0] + b[1].to_s } #=> "a0b1c2d3" You may want to write your own inject for this. require 'enumerator' module Enumerable def inject_with_index(*args) i = Enumerable::Enumerator.new(self, :each_with_index) if args.empty? i.inject do |a, b| yield(a[0], a[1], b[0], b[1]) end else i.inject(args[0]) do |a, b| yield(a, b[0], b[1]) end end end end Then you can call it less weirdly: ["a", "b", "c"].inject_with_index("") { |a, b, i| a << "#{b}@#{i}" } #=> "a@0b@1c@2" ["a", "b", "c"].inject_with_index do |a, i1, b, i2| [a + b, i1 + i2] end #=> ["abc", 3]