How can I use Array#delete while iterating over the array?
RubyArraysIterationRuby Problem Overview
I have an array that I want to iterate over and delete some of the elements. This doesn't work:
a = [1, 2, 3, 4, 5]
a.each do |x|
next if x < 3
a.delete x
# do something with x
end
a #=> [1, 2, 4]
I want a
to be [1, 2]
. How can I get around this?
Ruby Solutions
Solution 1 - Ruby
a.delete_if { |x| x >= 3 }
See method documentation here
Update:
You can handle x in the block:
a.delete_if do |element|
if element >= 3
do_something_with(element)
true # Make sure the if statement returns true, so it gets marked for deletion
end
end
Solution 2 - Ruby
You don't have to delete from the array, you can filter it so:
a = [1, 2, 3, 4, 5]
b = a.select {|x| x < 3}
puts b.inspect # => [1,2]
b.each {|i| puts i} # do something to each here
Solution 3 - Ruby
I asked this question not long ago.
https://stackoverflow.com/questions/2933366/deleting-while-iterating-in-ruby
It's not working because Ruby exits the .each
loop when attempting to delete something. If you simply want to delete things from the array, delete_if
will work, but if you want more control, the solution I have in that thread works, though it's kind of ugly.
Solution 4 - Ruby
Another way to do it is using reject!
, which is arguably clearer since it has a !
which means "this will change the array". The only difference is that reject!
will return nil
if no changes were made.
a.delete_if {|x| x >= 3 }
or
a.reject! {|x| x >= 3 }
will both work fine.