【问题标题】:Deleting While Iterating in Ruby?在 Ruby 中迭代时删除?
【发布时间】:2011-02-25 09:02:54
【问题描述】:

我正在迭代一个非常大的字符串集,它迭代一个较小的字符串集。由于大小,此方法需要一段时间才能完成,因此为了加快速度,我试图从较小的集合中删除不再需要使用的字符串。以下是我当前的代码:

    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

这对我来说有点草率。有没有更好的方法来做到这一点?

【问题讨论】:

  • 更简单的方法是什么?你想达到什么目标?
  • 你能不能不接受下面你自己的答案?这显然不是最好的

标签: ruby loops


【解决方案1】:

使用delete_if

array.delete_if do |v|
    if v.should_be_deleted?
        true
    else
        v.update
        false
    end
end

【讨论】:

  • 有趣的是:)。 ` array.delete_if { |v| v.should_be_deleted? }`
  • 如果他想以任何优雅的方式运行v.update,这一切都非常合理:)
  • 仅供参考,删除是立即的,所以如果块引发,更改仍会反映
  • Ruby 太有趣了
【解决方案2】:

使用'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]

【讨论】:

  • 这行不通 ``` a = [1,2,3,4] a.each do puts a.shift end 1 2 => [3, 4] ```跨度>
  • @Ivan 感谢您指出这一点。上次我没有对每个 do for array 进行测试,但确信 shift 会完成所需的工作。所以现在编辑它。检查一下!
  • 另外,Array#shift 效率低下,会导致 O(n²) 运行时间。
猜你喜欢
  • 1970-01-01
  • 2014-03-15
  • 2011-04-23
  • 1970-01-01
  • 2016-07-15
  • 2021-03-04
  • 2010-12-01
  • 1970-01-01
相关资源
最近更新 更多