k = [1,2,3,4,5]
for n in k
puts n
if n == 2
k.delete(n)
end
end
puts k.join(",")
# Result:
# 1
# 2
# 4
# 5
# [1,3,4,5]
# Desired:
# 1
# 2
# 3
# 4
# 5
# [1,3,4,5]
Этот же эффект происходит с другим итератором массива, k.each:
k = [1,2,3,4,5]
k.each do |n|
puts n
if n == 2
k.delete(n)
end
end
puts k.join(",")
имеет тот же результат.
Причина, по которой это происходит, довольно ясна... Ruby фактически не перебирает объекты, хранящиеся в массиве, а просто превращает их в симпатичный итератор индекса массива, начиная с индекса 0 и каждый раз увеличивая индекс пока он не закончится. Но когда вы удаляете элемент, он все равно увеличивает индекс, поэтому он не оценивает один и тот же индекс дважды, и я хочу его.
Это может быть не то, что происходит, но это лучшее, что я могу придумать.
Есть ли чистый способ сделать это? Есть ли уже встроенный итератор, который может это сделать? Или мне придется загрязнить его и сделать итератор индекса массива, а не увеличивать, когда элемент будет удален? (или итерации через клон массива и удаление из исходного массива)
Разъяснение
Я не просто хочу удалять элементы из массива; извините, если это было ясно. То, что я хотел бы сделать, это перебрать каждый элемент и "обработать" его; этот процесс иногда может удалить его. Чтобы быть более точным:
class Living_Thing
def initialize tracker,id
@tracker = tracker
@id = id
@tracker << self
end
def process
do_stuff
puts @id
if @id == 2
die
end
end
def die
do_stuff_to_die
@tracker.delete(self)
end
def inspect
@id
end
end
tracking_array = Array.new()
foo = Living_Thing.new(tracking_array,1)
bar = Living_Thing.new(tracking_array,2)
rab = Living_Thing.new(tracking_array,3)
oof = Living_Thing.new(tracking_array,4)
puts tracking_array.join(",") # => [1, 2, 3, 4]
for n in tracking_array
n.process
end
# result: only foo, bar, and oof are processed
В идеале, я хочу, чтобы все элементы в tracking_array обрабатывались.
Когда Living_Thing удаляется из track_array, необходимо вызывать Living_Thing # die; do_stuff_to_die очищает вещи, которые нужно класть вверх.