Ответ 1
В Ruby 1.9.2 Array#rindex
принимает блок: http://apidock.com/ruby/Array/rindex
Array#find_index
позволяет вам найти индекс первого элемента, который либо
object
, или Array#rindex
может позволить вам найти индекс последнего элемента, который равен object
, но есть ли что-нибудь, что позволяет вам найти индекс последнего элемента, который делает переданный ему блок возвратом true
В противном случае я должен сделать что-то вроде
last_index = array.length - 1 - array.reverse.find_index{|item| item.is_wanted?}
В Ruby 1.9.2 Array#rindex
принимает блок: http://apidock.com/ruby/Array/rindex
Такой позор до 1.9.2. Тем временем, если вы не хотите изменять свой массив, а скорее перечислите поиск в обратном порядке, вы можете сделать
last_index = array.length - 1 - array.rindex.find_index{|item| item.is_wanted? }
(1.8.7 и выше)
Или вы могли бы сделать что-то вроде
last_index = array.map {|i| i.is_wanted? }.rindex(true)
который немного красивее
Вы можете сделать небольшое улучшение лаконичности в своем обходном пути, удалив a.length, поскольку отрицательные индексы подсчитываются от конца строки в []
irb(main):015:0> a=[1,2,nil,6,8,nil,9,nil,10,11,12]
=> [1, 2, nil, 6, 8, nil, 9, nil, 10, 11, 12]
irb(main):016:0> -(a.reverse.index(nil)+1)
=> -4
irb(main):017:0> a[-4]
=> nil
По-прежнему кажется ужасно неэффективным, чтобы полностью изменить весь массив, когда все, что вы хотите сделать, - это перебрать его назад, но что ваша эффективность против решения эстетики вызывает
Это немного не по теме, но в любое время у вас есть коллекция с размером, и вы хотите получить результат другого размера, который вы можете использовать для ввода. В большинстве случаев он избегает ненужных операций цикла в коллекции ввода.
Например, если я хочу найти индекс последнего nil:
a = [1,2,nil,6,8,nil,9,nil,10,11,12]
# => [1, 2, nil, 6, 8, nil, 9, nil, 10, 11, 12]
a.inject([-1, nil]){|(current_index, matched), value| current_index += 1; matched = current_index if value.nil?; [current_index, matched]}.last
# => 7