Удаление во время итерации в Ruby? - PullRequest
14 голосов
/ 29 мая 2010

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

    Ms::Fasta.foreach(@database) do |entry|
        all.each do |set|
            if entry.header[1..40].include? set[1] + "|"
                startVal = entry.sequence.scan_i(set[0])[0]

                if startVal != nil
                    @locations << [set[0], set[1], startVal, startVal + set[1].length]
                    all.delete(set)
                end
            end
        end
    end

Проблема, с которой я сталкиваюсь, заключается в том, что простой способ, array.delete(string), эффективно добавляет оператор break во внутренний цикл, который портит результаты. Единственный способ, которым я знаю, как это исправить, это сделать:

Ms::Fasta.foreach(@database) do |entry|
        i = 0

        while i < all.length
            set = all[i]

            if entry.header[1..40].include? set[1] + "|"
                startVal = entry.sequence.scan_i(set[0])[0]

                if startVal != nil
                    @locations << [set[0], set[1], startVal, startVal + set[1].length]
                    all.delete_at(i)
                    i -= 1
                end
            end

            i += 1
        end
    end

Мне это кажется неаккуратным. Есть ли лучший способ сделать это?

Ответы [ 2 ]

38 голосов
/ 29 мая 2010

использование delete_if

array.delete_if do |v|
    if v.should_be_deleted?
        true
    else
        v.update
        false
    end
end
0 голосов
/ 14 марта 2013

используйте 'arr.shift'

a=[1,2,3,4]
while(a.length!=0)
  print a
  a.shift
  print "\n"
end

Выход:

[1, 2, 3, 4]
[2, 3, 4]
[3, 4]
[4]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...