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 从 tracking_array 中移除时, Living_Thing#die必须被调用;do_stuff_to_die 清理必须整理的东西。