Ruby найти в массиве со смещением - PullRequest
1 голос
/ 29 марта 2012

Я ищу способ сделать следующее в Ruby более понятным способом:

class Array
  def find_index_with_offset(offset, &block)
    [offset..-1].find &block
  end
end

offset = array.find_index {|element| element.meets_some_criterion?}
the_object_I_want = 
    array.find_index_with_offset(offset+1) {|element| element.meets_another_criterion?}

Поэтому я ищу в массиве Ruby индекс некоторого объекта, а затем делаю следующеепоиск, чтобы найти первый объект, который соответствует некоторому другому критерию и имеет более высокий индекс в массиве.Есть лучший способ сделать это?

Что я имею в виду под чистым: что-то, что не подразумевает явной нарезки массива.Когда вы делаете это пару раз, вычисление индексов нарезки быстро становится беспорядочным.Я хотел бы продолжать работать с исходным массивом.Это проще для понимания и менее подвержено ошибкам.

Примечание.В моем реальном коде у меня нет исправленного обезьяной массива, но я хочу обратить внимание на тот факт, что я ожидаю, что я дублирую существующую функциональность Array / Enumerable


Редактирование

  • Исправлено местоположение offset + 1 согласно комментарию Младена Яблановича;ошибка переписывания
  • Добавлено объяснение «чище» согласно комментарию Младена Яблановича

1 Ответ

2 голосов
/ 29 марта 2012

Очиститель здесь, очевидно, субъективный вопрос.Если вы стремитесь к краткости, я не думаю, что вы могли бы добиться большего, чем это.Если вы хотите иметь возможность связывать несколько таких находок или вам мешает нарезка, вы можете сделать что-то вроде этого:

module Enumerable
  def find_multi *procs
    return nil if procs.empty?
    find do |e|
      if procs.first.call(e)
        procs.shift
        next true if procs.empty?
      end
      false
    end
  end
end


a = (1..10).to_a
p a.find_multi(lambda{|e| e % 5 == 0}, lambda{|e| e % 3 == 0}, lambda{|e| e % 4 == 0})
#=> 8

Редактировать: И если вас не интересует производительность, вы можете сделатьчто-то вроде:

array.drop_while{|element|
  !element.meets_some_criterion?
}.drop(1).find{|element|
  element.meets_another_criterion?
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...