I have an array of ~1200 ruby objects and I want to loop over them and delete the ones with names that contain words or parts of words.
So I tried this:
list.each do |item|
if item.name =~ /cat|dog|rat/i
puts item.name
list.delete(item)
end
end
It works, except that it seems to miss some items with names that should match. If I run it again it finds a few more, and if I run it another time it finds a few more. It finds less each time, but I have to run it 3 times in order to delete everything.
Why in the world is this happening?
That's you modifying underlying collection while iterating over it.
Basically, if collection changes in some way during iteration (becomes empty, gets prepended with a new element, etc), iterator doesn't have a lot of ways to handle it.
Try reject instead.
list.reject! {|item| item.name =~ /cat|dog|rat/i }
There is another way to do the same as reject!
with delete
:
list.delete_if { |item| item =~ /cat|dog|rat/i }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With