yaboiduke
yaboiduke

Reputation: 670

Ruby: Collect index from Array/String Matchdata

I'm new to Ruby, here's my problem : I would like to iterate through either an Array or String to obtain the index of characters that match a Regex.

Sample Array/String

 a = %q(A B A A C C B D A D)
 b = %w(A B A A C C B D A D)

What I need is something for variable a or b like ;

#index of A returns;
[0, 2, 3,8]

#index of B returns
[1,6]

#index of C returns
[5,6]
#etc

I've tried to be a little sly with

z = %w()

a =~ /\w/.each_with_index do |x, y|

 puts z < y

end

but that didn't workout so well. Any solutions ?

Upvotes: 1

Views: 410

Answers (3)

LukasMac
LukasMac

Reputation: 898

If you want to count occurrences of each letter you can define helper method:

def occurrences(collection)
  collection = collection.split(/\s/) if collection.is_a? String

  collection.uniq.inject({}) do |result, letter|
    result[letter] = collection.each_index.select { |index| collection[index] == letter }
    result
  end
end

# And use it like this. This will return you a hash something like this: 
# {"A"=>[0, 2, 3, 8], "B"=>[1, 6], "C"=>[4, 5], "D"=>[7, 9]}
occurrences(a)
occurrences(b)

This should work either for String or Array.

Upvotes: 0

Stefan
Stefan

Reputation: 114218

If you want to get each character's index as a hash, this would work:

b = %w(A B A A C C B D A D)

h = {}
b.each_with_index { |e, i|
  h[e] ||= []
  h[e] << i
}
h
#=> {"A"=>[0, 2, 3, 8], "B"=>[1, 6], "C"=>[4, 5], "D"=>[7, 9]}

Or as a "one-liner":

b.each_with_object({}).with_index { |(e, h), i| (h[e] ||= []) << i }
#=> {"A"=>[0, 2, 3, 8], "B"=>[1, 6], "C"=>[4, 5], "D"=>[7, 9]}

Upvotes: 1

xdazz
xdazz

Reputation: 160883

For array, you could use

b.each_index.select { |i| b[i] == 'A' }

For string, you could split it to an array first (a.split(/\s/)).

Upvotes: 3

Related Questions