Alle mercoledì 26 dicembre 2007, Marco ha scritto:
Hi, some newbie questions…
- 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
first part of your question, notice that String#index (unlike
Array#index)
accept an optional offset argument. You can then do something like:
str =“a test string”
positions = []
pos = -1
while (pos = s.index(your_pattern, pos + 1))
positions << pos
end
After running this code, positions will contain the indices of all the
occurrences of your_pattern (which can be any argument String#index
accepts)
inside str.
To get the index of the n-th occurrence, you can extract the n-th
element from
such an array, or add a counter to the while cycle.
- 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
a1=%w[a b c d]
a2=[2, 3, 5, 6]
and want to get the letters in a1 in the same places of even numbers in
a2
(i.e, [“a”, “d”]).
These are some approaches (you need to do require ‘enumerator’ before
all of
them):
a1.enum_for(:each_with_index).select{|e, idx| a2[idx]%2==0}
=> [[“a”, 0], [“d”, 3]]
This returns an array of the pairs of the letter and its index. You can
then
extract the letters with map.
a1.enum_for(:each_with_index).inject([]){|res, i|
a2[i[1]]%2 == 0 ? res << i[0] : res }
=> [“a”, “d”]
a1.enum_for(:each_with_index).map{|e, idx| a2[idx]%2==0 ? e :
nil}.compact
This will not work if a1 can contain nil elements (because they also
would be
removed by nil).
I hope this helps
Stefano