Is there an equivalent of Array#find_index for the last index in ruby?

Array#find_index allows you to find the index of the first item that either

  • is equal to an object, or
  • makes a block passed to it evaluate to true

Array#rindex can allow you to find the index of the last item that is equal to an object, but is there anything that allows you to find the index of the last item that makes a block passed to it return true?

Otherwise, should I do something like

last_index = array.length - 1 - array.reverse.find_index{|item| item.is_wanted?}
14
задан Andrew Grimm 12 January 2012 в 00:52
поделиться

5 ответов

В Ruby 1.9.2 Array#rindex принимает блок: http://apidock.com/ruby/Array/rindex

17
ответ дан 1 December 2019 в 13:20
поделиться

Какая досада до 1.9.2. В то же время, если вы не хотите перевернуть свой массив, а, скорее, перечислите поиск в обратном порядке, вы можете выполнить

last_index = array.length - 1 - array.rindex.find_index {| item | item.is_wanted? } (1.8.7 и выше)

1
ответ дан 1 December 2019 в 13:20
поделиться

Вы можете немного улучшить краткость своего обходного пути, удалив 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

По-прежнему кажется ужасно неэффективным перевернуть весь массив, когда все, что вам нужно, - это перебирать его в обратном направлении, но это ваша оценка эффективности и эстетики.

0
ответ дан 1 December 2019 в 13:20
поделиться

Это немного не по теме, но каждый раз, когда у вас есть коллекция с размером, и вы хотите получить результат другого размера, вы можно использовать инъекцию. В большинстве случаев он позволяет избежать ненужных операций цикла с входной коллекцией.

Например, если я хочу найти индекс последнего нуля:

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
0
ответ дан 1 December 2019 в 13:20
поделиться

Или вы можете сделать что-то вроде

last_index = array.map {|i| i.is_wanted? }.rindex(true)

, что немного красивее

1
ответ дан 1 December 2019 в 13:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: