Как я могу использовать Array # delete во время перебора массива? - PullRequest
65 голосов
/ 16 июля 2010

У меня есть массив, который я хочу перебрать и удалить некоторые элементы. Это не работает:

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]. Как я могу обойти это?

Ответы [ 4 ]

114 голосов
/ 16 июля 2010

a.delete_if { |x| x >= 3 }

См. Документацию по методике здесь

Обновление:

Вы можете обработать х в блоке:

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
7 голосов
/ 16 июля 2010

Вам не нужно удалять из массива, вы можете отфильтровать его так:

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 голосов
/ 16 июля 2010

Я задал этот вопрос не так давно.

Удаление при итерации в Ruby?

Это не работает, потому что Ruby выходит из цикла .each при попытке удалить что-то. Если вы просто хотите удалить вещи из массива, delete_if сработает, но если вам нужен больший контроль, решение, которое у меня есть в этом потоке, сработает, хотя и выглядит некрасиво.

2 голосов
/ 07 марта 2014

Другой способ сделать это - использовать reject!, что, возможно, более понятно, так как имеет !, что означает «это изменит массив».Единственное отличие состоит в том, что reject! вернет nil, если не было внесено никаких изменений.

a.delete_if {|x| x >= 3 }

или

a.reject! {|x| x >= 3 }

будут работать нормально.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...