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?
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]
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
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]
['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.
In the interest of readability, I would use the following:
my_array.each_index.select {|idx| my_array[idx].start_with?("bo") }
Array#[] was scolded in the previous item :)
my_array.grep(/^bo/)will suffice.