Deleting values from tables - how to do it completely?

I have a piece of code that runs through a table to see if anything in that table matches. More specifically, the code checks if the current floor matches any “.floor” value in the table. The problem is, once it’s checked, I’d like to delete that value from the table altogether, but I don’t know how to do that. My current method doesn’t work because if you run ‘function selectPeople’ twice, it throws and error because “persontable[i]:removeSelf()” appears to try to remove a nil value. What is the proper way to delete a value in a table completely?

local function selectPeople(floor)  
  
 local i  
  
 for i = 1,table.maxn(persontable) do  
  
 if ( persontable[i].floor == floor ) then  
  
 persontable[i]:removeSelf()  
  
 table.remove (persontable[i])  
   
 end  
   
end  

Hope that makes sense - thanks! [import]uid: 78150 topic_id: 21499 reply_id: 321499[/import]

is persontable[i].floor a display object?

If all you are trying to do is remove the table point than

table.remove(persontable[i])  

should be fine [import]uid: 23649 topic_id: 21499 reply_id: 85089[/import]

If this code:

table.remove(persontable[i])   

was removing the table point properly, then running the function more than once wouldn’t cause an error.

What seems to be happening when I run the code more than once is that the If statement at the start of the fucntion is finding a persontable[i].floor with a value of the current floor, even though I used the table.remove function to remove the point.

For example, if I add to the very end of the function

persontable[i].floor = 999  

I change the value in the table to a floor that is impossibly high, this avoids causing the error since the if statement at the start of the function will always be false… but this is further evidence that I’m not deleting table points properly.

Can anyone help?

[import]uid: 78150 topic_id: 21499 reply_id: 85215[/import]

Try this:

local function selectPeople(floor) local i for i = 1,table.maxn(persontable) do if persontable[i] ~= nil then if ( persontable[i].floor == floor ) then persontable[i]:removeSelf() persontable[i] = nil collectgarbage("collect") table.remove (persontable[i]) end end end end [import]uid: 19626 topic_id: 21499 reply_id: 85259[/import]

Personally I would do :

[code]
local function selectPeople(floor)

local i

for i = 1,table.maxn(persontable) do

if ( persontable[i].floor == floor ) then

display.remove(persontable[i])

persontable[i] = nil

end

end [import]uid: 84637 topic_id: 21499 reply_id: 85262[/import]

The problem with that Danny is two fold.

First, as I found out recently, #tablename which returns the length of the table will return a number too small if there is a nil entry in the table. I’m assuming that table.maxn() has the same behavior.

In other words:

t = { 1, 2, 3, 4, 5}
print(#t) – 5
t = { 1, 2, nil, 4, 5}
print(#t) – 2

If table.maxn() does the same, then the loop will never reach 4 and 5.

To work around this problem, you have two choices:

  1. Don’t use #tablename or table.maxn() and just have a maxSize variable and then as you loop through the table, test for tablename[i] being nil and only process it if its not.

  2. Remove the empty table entry completely to avoid the nil entries. But depending on how fast this runs, removing the table entry before garbage collection runs could cause a memory leak. I could be wrong about this, but this is what it seems to be.

Please correct me if I’m wrong on this stuff. Even though I’ve been programming in Corona for about a year, there is still a lot of the magic under the hood I don’t understand with all of this memory management stuff.
[import]uid: 19626 topic_id: 21499 reply_id: 85290[/import]

Thanks for the responses everyone!

Before posting, I had tried everything suggested except:

 collectgarbage("collect")  

Once I included it, the error went away.
Robmiracle,

FYI: “table.maxn()” doesn’t actually suffer from the same problem that the “#tablename” method suffers from regarding the hiccups caused by nil’s. “table.maxn()” checks from the first instance to the “maximum” instance in a table, regardless of whether there are nils in between.

That was a lesson I learned through lots of struggling, blood sweat and tears… so I thought I’d share.
Thanks again =)

[import]uid: 78150 topic_id: 21499 reply_id: 85373[/import]