Stefano Crocco
12/26/2007 9:28:00 AM
Alle mercoled=EC 26 dicembre 2007, Marco ha scritto:
> Hi, some newbie questions...
>
> 1) How can I obtain all the indices of the occurrences of a pattern in a
> string (and not only the index of the first one using "index")? And the
> index of the n-th occurrence?
I'm sure there's a better solution, but I can't think of it right now. For =
the=20
first part of your question, notice that String#index (unlike Array#index)=
=20
accept an optional offset argument. You can then do something like:
str =3D"a test string"
positions =3D []
pos =3D -1
while (pos =3D s.index(your_pattern, pos + 1))
positions << pos
end
After running this code, positions will contain the indices of all the=20
occurrences of your_pattern (which can be any argument String#index accepts=
)=20
inside str.
To get the index of the n-th occurrence, you can extract the n-th element f=
rom=20
such an array, or add a counter to the while cycle.
> 2) What's the simplest way to select elements of a vector,on the basis of=
a
> condition on a second vector of the same length?
It depends on what your needs exactly are. Suppose you have the two arrays=
=20
a1=3D%w[a b c d]
a2=3D[2, 3, 5, 6]
and want to get the letters in a1 in the same places of even numbers in a2=
=20
(i.e, ["a", "d"]).
These are some approaches (you need to do require 'enumerator' before all o=
f=20
them):
a1.enum_for(:each_with_index).select{|e, idx| a2[idx]%2=3D=3D0}
=3D> [["a", 0], ["d", 3]]
This returns an array of the pairs of the letter and its index. You can the=
n=20
extract the letters with map.
a1.enum_for(:each_with_index).inject([]){|res, i|=20
a2[i[1]]%2 =3D=3D 0 ? res << i[0] : res }
=3D> ["a", "d"]
a1.enum_for(:each_with_index).map{|e, idx| a2[idx]%2=3D=3D0 ? e : nil}.comp=
act
This will not work if a1 can contain nil elements (because they also would =
be=20
removed by nil).
I hope this helps
Stefano