the general case of iterating over an array and removing random items from the middle while continuing to iterate
If you're iterating front-to-back, when you remove element N, the next element in your iteration (N+1) gets shifted down into that position. If you increment your iteration variable (as ipairs does), you'll skip that element. There are two ways we can deal with this.
Using this sample data:
input = { 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p' }
remove = { f=true, g=true, j=true, n=true, o=true, p=true }
We can remove input
elements during iteration by:
Iterating from back to front.
for i=#input,1,-1 do
if remove[input[i]] then
table.remove(input, i)
end
end
Controlling the loop variable manually, so we can skip incrementing it when removing an element:
local i=1
while i <= #input do
if remove[input[i]] then
table.remove(input, i)
else
i = i + 1
end
end
For non-array tables, you iterate using next
or pairs
(which is implemented in terms of next
) and set items you want removed to nil
.
Note that table.remove
shifts all following elements every time it's called, so performance is exponential for N removals. If you're removing a lot of elements, you should shift the items yourself as in LHF or Mitch's answer.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…