Index of the n-th occurrence

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?

  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?

Thanks,

                  Marco

Alle mercoledì 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
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.

  1. 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

Marco wrote:

  1. 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?

res=[]
[1,2,3,4].zip([2,4,9,16]) {|x,y| res << x if y==x*2}
res #=> [1,2]

HTH,
Sebastian

On Dec 26, 1:53 am, “Marco” [email protected] wrote:

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?

Why do you want these indices? There may be an easier
way to accomplish your goal. Ruby isn’t APL.

a = []
==>[]
“the thug’s thews”.scan(/.*?(th)/){ a << $~.begin(1) }
==>“the thug’s thews”
a
==>[0, 4, 11]

On Dec 26, 8:53 am, “Marco” [email protected] wrote:

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?

Hi
perhaps you can find something useful in ruby core doc RegExp/
MatchData
it seems that the method offset is good for you

mtch.offset(n) => array

Returns a two-element array containing the beginning and ending
offsets of the nth match.

Tom

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs