PakiPat
PakiPat

Reputation: 1085

How to search for multiple elements in Ruby array using regexp

Given:

my_array = ['america', 'bombay', 'bostwana', 'cameroon']

I can locate the index of the first element that, say, begins with 'bo' with

my_array.find_index { |l| l.start_with? 'bo' }

How can I locate all such elements?

Upvotes: 1

Views: 1253

Answers (4)

Jordan Running
Jordan Running

Reputation: 106147

In the interest of readability, I would use the following:

my_array.each_index.select {|idx| my_array[idx].start_with?("bo") }

Upvotes: 0

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121010

['america', 'bombay', 'bostwana', 'cameroon']
  .each_with_index # to get indices
  .grep(->(e) { e.first.start_with? "bo" }) # I ❤ Enumerable#grep
  .map(&:last) # get indices
#⇒ [1, 2]

I posted this to show the approach that is rarely used. Enumerable#grep accepts anything, that is used to select items basing on triple-equal case comparison.

Passing Proc instance there is cool, because Proc has a default Proc#=== implementation: it’s simply being invoked on receiver.

Upvotes: 0

Scott Bartell
Scott Bartell

Reputation: 2840

You can use map.with_index with a conditional and compact the result.

my_array.map.with_index{ |element, index| index if element.start_with? 'bo' }.compact

How this works

map

map will take all of the values and "map" them to the value that is returned when each item is passed into the given block.

my_array.map { |element| element.start_with? 'bo' }
# => [false, true, true, false]

with_index

To get the index values you can use with_index like this:

my_array.map.with_index { |element, index| index }
# => [0, 1, 2, 3]

my_array.map.with_index { |element, index| index if element.start_with? 'bo' }
# => [nil, 1, 2, nil]

compact

Then, to get rid of the nil values you can call compact on the returned array.

my_array.map.with_index{ |element, index| index if element.start_with? 'bo' }.compact
# => [1, 2]

Upvotes: 1

ndnenkov
ndnenkov

Reputation: 36110

If you want the elements:

my_array.find { |element| element.start_with? 'bo' }   # => "bombay"
my_array.select { |element| element.start_with? 'bo' } # => ["bombay", "bostwana"]

If you want the indices:

my_array.index { |element| element.start_with? 'bo' } # => 1
my_array.map.with_index.select { |element, _| element.start_with? 'bo' }.map(&:last)
  # => [1, 2]

Upvotes: 1

Related Questions