Как я могу использовать индекс или rindex с блоком в Ruby? - PullRequest
3 голосов
/ 10 ноября 2009

Есть ли встроенная функция Array или Enumerable, которая позволяет мне искать элемент с помощью блока и возвращать его индекс?

Что-то вроде:

ar = [15,2,33,4,50,69]
indexes = ar.find_indexes {|item| item > 4 == 0}
# indexes will now contain 0,2,4,5

Было бы очень легко добавить свою собственную, но я хотел бы знать, существует ли она уже?

Ответы [ 5 ]

7 голосов
/ 10 ноября 2009

Я не думаю, что есть что-то встроенное, по крайней мере, я не заметил ничего ранее необнаруженного в Array или Enumerable docs.

Это довольно лаконично:

(0..ar.size-1).select { |i| ar[i] > 4 }

РЕДАКТИРОВАТЬ: Должен был упомянуть, что это Ruby 1.8.6.

ДРУГОЕ РЕДАКТИРОВАНИЕ: забыли тройную точку, которая сохраняет весь персонаж, а также убирает -1, что мне было неудобно:

(0...ar.size).select { |i| ar[i] > 4 }
3 голосов
/ 10 ноября 2009

Я так понимаю, это только ruby ​​1.9

indexes = ar.collect.with_index { |elem, index| index if elem > 4 }.
             select { |elem| not elem.nil? }

РЕДАКТИРОВАТЬ: для ruby ​​1.8 попробуйте

require 'enumerator'
indexes = ar.to_enum(:each_with_index).
             collect { |elem, index| index if elem > 4 }.
             select { |elem| not elem.nil? }
1 голос
/ 10 ноября 2009

Нет, но вы всегда можете сделать это, если хотите:

class Array
  def find_indexes(&block)
    (0..size-1).select { |i| block.call(self[i]) }
  end
end

ar = [15,2,33,4,50,69]
p ar.find_indexes {|item| item > 4 }  #=> [0, 2, 4, 5]                                                        
1 голос
/ 10 ноября 2009

Просто дай взорваться силе метода впрыска !!! ; -)

ar.inject([]){|a,i| a.empty? ? a << [0, i] : a << [a.last[0]+1,i]}
  .select{|a| a[1] > 4}
  .map{|a| a[0]}

(работает с ruby ​​1.8.6)

0 голосов
/ 10 ноября 2009

Это, по сути, ответ Майка Вудхауса, переформатированный, чтобы удалить уродливый диапазон.

ar.each_index.select{|item| item > 4}

Вот вариант ответа johnanthonyboyd, который работает с Ruby 1.8.7

ar.enum_with_index.each.select{|item| item.first > 4}.map(&:last)
...