Ruby push и удалить ошибку?
У меня есть этот код, и я не знаю, почему он не дает мне правильный ответ
list = [1]
a = [0,0,2,3,4]
for n in a
if n!= 0
list.push(n)
a.delete(n)
end
end
p list => [1,2,4]
p a => [0,0,3]
Я не понимаю, почему номер не был добавлен в список. Когда я попытался использовать только "push", а не "a.delete", я получил правильные ответы
list = [1,2,3,4]
a = [0,0,2,3,4]
Что здесь происходит?
2 ответа
Внимательно посмотрите на вывод:
list = [1]
a = [0,0,2,3,4]
for n in a
if n!= 0
list.push(n)
a.delete(n)
p list,a
end
end
Выход:
[1, 2]
[0, 0, 3, 4]
[1, 2, 4]
[0, 0, 3]
Поэтому, когда ваш цикл удален 2
, который был в 3-м пункте до удаления, 3 приходит в эту позицию. И когда цикл завершил обработку 3-го элемента, он перейдет к следующему элементу из коллекции, который будет равен 4. Это - то, как элемент 3 будет пропущен. Как и после удаления все ваши элементы будут смещены справа налево. Посмотрите ниже для большей ясности, чтобы увидеть, что происходит внутри цикла и состояние сбора a
после каждого удаления.
list = [1]
a = [0,0,2,3,4]
for n in a
if n!= 0
p n
i = a.find_index(n)
list.push(n)
a.delete(n)
p a[i]
p "-" *8
end
end
выход:
2
3
"--------"
4
nil
"--------"
Правило номер один для повторяющихся коллекций: не меняйте коллекцию, которую вы сейчас повторяете!,
Быстрое решение проблемы - перебрать копию коллекции.
list = [1]
a = [0,0,2,3,4]
for n in a.dup # here, a copy
if n!= 0
list.push(n)
a.delete(n)
end
end
list # => [1, 2, 3, 4]
a # => [0, 0]