How can I delete objects from a table while iterating through it?

Every time I destroy an object in my game, I create a text display object indicating how many points I just earned. These float gently up the screen and also fade out.

I want to be sure I am freeing up everything correctly as I go, so would my best bet be something like:for i = #imagesTable, 1, -1 do -- Here I do whatever I want with each image -- Then if for whatever reason I want to remove the item, I set 'shouldDie' = true, and do the following: if shouldDie == true then local child = table.remove(imagesTable, i) if child ~= nil then child:removeSelf() child = nil end end end(Based on sample code found on the forums by FFM).
I’ve been using for i,v in ipairs() do up to now, but have no idea how or if I can delete items in it safely while iterating through it.

I also have another problem - a list that contains animating sprite sheets (particle effects in fact) that I wish to remove when they finish animating. Rather than have a time counter for each one and a system such as above, what I’d done is setup a callback from when the animation finishes. To not have to iterate manually through the list to find the matching particle effect and remove it, I had been using the image as both the key and the value, and then to remove it I was just doing: imagesTable[object] = nil object:removeSelf()Is this acceptable and safe code?
[import]uid: 46639 topic_id: 13653 reply_id: 313653[/import]

Using ipairs/pairs to iterate and table.remove will cause issues as the element is completely removed from the table and everything is moved up by one. Which means the next element in the table is now where the element you just removed was so when the iterator advances it skips the element that was the next element but it now the current element.

You can just nil the elements with (i)pairs and things will be fine but if you want to use table.remove then use the for loop running from the end like the example you have.

imagesTable[object] = nil  
object:removeSelf()  

looks like you’re going to be calling removeSelf() on nil [import]uid: 68937 topic_id: 13653 reply_id: 50226[/import]

I’m trying to iterate through a table and when I remove ONE object everything works fine, when I remove more than one object from the table the length of the table goes down to 1 for some reason.

Here is a sample code to show the problem I’m having. Can anyone help me out?
[lua]tileList = {}

for i = 1, 5, 1 do
local instance = display.newRect(0,0, 40, 40)
instance:setFillColor(tonumber(“BB”, 16), tonumber(“BB”, 16), tonumber(‘BB’,16))
instance.x = display.contentWidth / 2
instance.y = ( display.contentHeight / 4 ) + ( i * (instance.contentHeight + 3))
table.insert(tileList , instance)
end

for i = 1, #tileList, 1 do
if i == 2 then
local object = tileList[i]
tileList[i] = nil
object:removeSelf()
end

–[[
if i == 4 then
local object = tileList[i]
tileList[i] = nil
object:removeSelf()
end
]]–
end

print(#tileList)

function cleanTable(TABLE)
local removeList = {}
for i = 1, #TABLE, 1 do
if TABLE[i] == nil then
table.insert(removeList, i)
end
end

for i = 1, #removeList, 1 do
table.remove(TABLE, removeList[i])
end
end
cleanTable(tileList)
print(#tileList)[/lua]

If you uncomment out the section in the center of the loop the length SHOULD be 3 but it comes out as 1. Any help? [import]uid: 74542 topic_id: 13653 reply_id: 50297[/import]

if you used pairs to loop through the array you’d find it still had all the elements it should have. You’re running into an issue with the # operator, use table.getn( your_table ) and you’ll get the expected result.

2.5.5 - The Length Operator

The length operator is denoted by the unary operator #. The length of a string is its number of bytes (that is, the usual meaning of string length when each character is one byte).

The length of a table t is defined to be any integer index n such that t[n] is not nil and t[n+1] is nil; moreover, if t[1] is nil, n can be zero. For a regular array, with non-nil values from 1 to a given n, its length is exactly that n, the index of its last value. If the array has “holes” (that is, nil values between other non-nil values), then #t can be any of the indices that directly precedes a nil value (that is, it may consider any such nil value as the end of the array).

Also, for a bog standard for loop where it’s just incrementing by 1 you don’t need to specify the step size. [import]uid: 68937 topic_id: 13653 reply_id: 50313[/import]

Just a quick post to say thanks to Matthew. Much appreciated. [import]uid: 46639 topic_id: 13653 reply_id: 52324[/import]