Stefano Crocco
8/23/2007 11:11:00 AM
Alle giovedì 23 agosto 2007, Ronald Fischer ha scritto:
> For an array a, I would like to know all the indices i where a[i]
> fulfils
> some condition. My solution (which works) looks like this:
>
> a=%w(Deutschlandsberg Stainz Preding Eibiswald)
> (0...a.size).select {|i| a[i]=~/g$/} # ==> [0,2]
>
> What I don't like with this solution is that inside the code block
> supplied to select, I also have to access the array variable a which
> is declared outside. I would prefer having my code block "self
> contained", using only the variables passed as parameter.
>
> Is there in Ruby a function similar select, where I also get the array
> element passed through, kind of:
>
> a.select_index {|index,value| value?~/g$/}
>
> or do I have to write my own here? I don't want to reinvent the
> wheel....
>
> Ronald
You can do this:
require 'enumerator'
a.enum_for(:each_with_index).select{|value, index value.match /g$/
}.map{|value, index| index}
enum_for returns an object of class Enumerable::Enumerator whose each method
calls the argument of enum_for, in this case each_with_index. select then
returns an array of pairs [value, index], where value are matching values and
index their index in a. To extract only the indices, map is called on this
array. The downside of this approach is that it needs two iterations: one on
the original array and one on the array of matching results. If this is a
problem, you can use this:
a.enum_for(:each_with_index).inject([]){|res, i|
i[0].match( /g$/) ? res << i[1] : res
}
or
matching = []
a.enum_for(:each_with_index).each{|value, index|
matching << index if value.match(/g$/)
}
I hope this helps
Stefano