Как я могу использовать Array # delete во время итерации по массиву?
У меня есть массив, который я хочу перебрать и удалить некоторые элементы. Это не работает:
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]
Я хочу a
быть [1, 2]
. Как я могу обойти это?
Ответы
Ответ 1
a.delete_if { |x| x >= 3 }
См. документацию по методике здесь
Update:
Вы можете обрабатывать x в блоке:
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
Ответ 2
Вам не нужно удалять из массива, вы можете его фильтровать так:
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
Ответ 3
Я задал этот вопрос совсем недавно.
Удаление во время итерации в Ruby?
Он не работает, потому что Ruby завершает цикл .each
при попытке удалить что-то. Если вы просто хотите удалить объекты из массива, delete_if
будет работать, но если вы хотите большего контроля, то решение, которое у меня есть в этом потоке, работает, хотя оно вроде уродливо.
Ответ 4
Другой способ сделать это - использовать reject!
, который, возможно, более ясен, поскольку имеет !
, что означает "это изменит массив". Единственное отличие состоит в том, что reject!
вернет nil
, если никаких изменений не было.
a.delete_if {|x| x >= 3 }
или
a.reject! {|x| x >= 3 }
оба будут работать нормально.