从数组中删除项目需要多次传递才能将它们全部删除

Set*_*own 13 ruby regex

我有一个~1200个ruby对象的数组,我想循环遍历它们并删除名称中包含单词或部分单词的对象.

所以我尝试了这个:

list.each do |item|
  if item.name =~ /cat|dog|rat/i
    puts item.name
    list.delete(item)
  end
end
Run Code Online (Sandbox Code Playgroud)

它的工作原理,除了它似乎错过了一些名称应该匹配的项目.如果我再次运行它会发现更多,如果我再次运行它会发现更多.它每次都找不到,但我必须运行它3次才能删除所有内容.

世界上为什么会发生这种情况?

Nik*_*bak 25

那是你在迭代它时修改底层集合.
基本上,如果集合在迭代期间以某种方式发生变化(变为空,前缀为新元素等),则迭代器没有很多方法来处理它.

请尝试拒绝.

list.reject! {|item| item.name =~ /cat|dog|rat/i }
Run Code Online (Sandbox Code Playgroud)

  • @sawa [猫,猫,猫,猫] - > [猫,猫] - > [猫] - > [] (4认同)
  • 拒绝!更好,但如果由于某种原因你不得不迭代,你可以反向迭代,所以你在迭代后面而不是在它之前删除. (3认同)
  • @Seth Documentation没有告诉我们:)但是如果Ruby中的`array.each`是使用索引实现的(这似乎是合乎逻辑的),那就会发生. (2认同)