2009-11-10 1 views
3

Есть ли встроенный массив Array или Enumerable, который позволяет мне искать элемент с использованием блока и возвращать его индекс?Как я могу использовать индекс или rindex с блоком в Ruby?

Что-то вдоль линий:

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

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

ответ

7

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

Это довольно лаконичным, хотя:

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

EDIT: Если уже упоминали это Руби 1.8.6.

ДРУГОЙ EDIT: забыл тройную точку, которая сохраняет весь характер, а также очистку -1, что я не был комфортно:

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

Я понимаю, что это только рубин 1,9

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

EDIT: рубин 1.8 попробовать

require 'enumerator' 
indexes = ar.to_enum(:each_with_index). 
      collect { |elem, index| index if elem > 4 }. 
      select { |elem| not elem.nil? } 
+0

'xs.select {| эль | не elem.nil? } '->' xs.compact' – tokland

0

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

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

Вот вариант ответа johnanthonyboyd, которая работает с Руби 1.8.7

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

Невозможно увидеть, как работает [each_index] (http://ruby-doc.org/core/classes/Array.html#M002174) - ему нужно будет вернуть Enumerable , не так ли? enum_with_index выглядит полезным, но следует учитывать, что он имеет значение 1,8.7 и выше, а также удобная карта (&: ...) (вне Rails). Кроме того, документы предполагают, что для этого требуется 'require enumerator'. Я все еще на 1.8.6, поэтому я не могу проверить. –

+0

Каждый и каждый_индекс и другие методы итератора возвращают объект Enumerable, через который он выполнял итерацию. Что касается синтаксиса другого, он работал в моей локальной установке irb (с использованием ruby ​​1.8.7, я не понимал, что это недавнее дополнение) – EmFi

+0

Я предполагаю, что вы имели в виду: 'ar.each_index.select {| idx | ar [idx]> 4} ' – tokland

1

Просто дайте взрывается сила методы нагнетающей !!! ;-)

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

(работает с рубином 1.8.6)

+0

Это должно быть приятно отлаживать. – Geo

+0

Конечно, но, к счастью, отладки нет необходимости;) – Erlock

+0

Этого никогда не будет. Пока не будет :) – Geo

1

Нет, но вы можете всегда обезьяна патч, если вы хотите:

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]               
+0

Да, я знаю, что это вариант, но я подумал, что, возможно, что-то уже существовало. – Geo

 Смежные вопросы

  • Нет связанных вопросов^_^