'#table' or 'table.maxn'?

Okay another appallingly stupid question.

I’m dealing with tables of items in my game. I have army guys (units) who get killed during a level, then the next level I need to do some housework, clean out the dead wood from the tables etc. Then carry on.

When a unit dies, it is set to unit[i].isDead=TRUE and it’s physics body is removed and all its graphics set to alpha=0.

At the end of a level I have a ‘purge’ which goes through the unit table, picks out all the unit[i].isDead=TRUE guys, nils all their content and then removes the table entry. (My FOR loop counts downwards…btw ;) )

The very next bit of code in my purge function re-numbers all the guys in the table so their table key matches their ID number: (e.g.: unit[i].myNumber = i)

Then, the next level begins.

At the moment when I process the unit table, I’m flipping between:  for i = 1,#unit do and **for i=table.maxn(unit) do ****…**but I’m not I’m not sure which I should be using! As far as I understand it, using #table in a for loop results in the code counting all the table entries that contain something…UNTIL it hits a nil entry? (which could mean units after that nil entry wouldn’t be processed?)

While the table.man method is more thorough and goes through every entry even though it might have nothing (a nil) in it. Is this right? I’ve looked for more info on #table but can’t find anything that explains what exactly the # means in terms of running through a table.

Grateful for any help here.

best

Alex

sounds like you understand it correctly.

lua tries to “guess” if you’re using a table like a sequential numeric array, and will optimize its internal storage and access if so. otherwise it always defaults to standard associative array (aka “hash table”) behavior.  fe, if you’re nil’ing numeric indicies at arbitrary positions of what BEGAN AS a sequential array, then you’ll end up with a sparse array.

the # operator is the guessed size of the sequential numeric array

the maxn() function returns the highest numeric key, sequential or not

(when the two don’t agree, it means you have a non-sequential “sparse array”)

fwiw, it’s actually easier to abandon numeric arrays and just use an arbitrary hash key, then iterate with pairs(), then nil’ing entries won’t affect subsequent traversal.  (caveat: unless you have a requirement to traverse the list in a specified order)

Thanks for that Dave. a relief to know I kind of got it right. :slight_smile:

Hi Alex.

To add to the above,  #table is the index before a  nil , but not necessarily the first one, so in the presence of holes you could end up encountering others in between. (ipairs(), on the other hand, does stop at the first nil , though this would break if Corona adopted newer flavors of Lua.) This seems like an odd design, but it’s more the case that, when a table is treated as an array, the “proper” behavior falls out of it, so it was convenient to expose it; break the contract and it’s a crapshoot.

table.maxn() does a brute-force review of the table, yes. This is of the underlying keys, though, which include the integers. If you had something like 

local t = { 3, 23, 3, 23, 1 } t[324242] = 2

and tried to count t , it wouldn’t need to iterate over the 324236 missing entries.

The situation where you need to be able to remove elements while keeping other elements’ indices intact is essentially what my Stable Array plugin addresses, in case that’s of interest. It also has an iterator. (Apologies for its rather rambling description. The bit about “cycles” in particular does a disservice to Lua’s garbage collector, which handles them fine except in certain circumstances involving weak tables.)

sounds like you understand it correctly.

lua tries to “guess” if you’re using a table like a sequential numeric array, and will optimize its internal storage and access if so. otherwise it always defaults to standard associative array (aka “hash table”) behavior.  fe, if you’re nil’ing numeric indicies at arbitrary positions of what BEGAN AS a sequential array, then you’ll end up with a sparse array.

the # operator is the guessed size of the sequential numeric array

the maxn() function returns the highest numeric key, sequential or not

(when the two don’t agree, it means you have a non-sequential “sparse array”)

fwiw, it’s actually easier to abandon numeric arrays and just use an arbitrary hash key, then iterate with pairs(), then nil’ing entries won’t affect subsequent traversal.  (caveat: unless you have a requirement to traverse the list in a specified order)

Thanks for that Dave. a relief to know I kind of got it right. :slight_smile:

Hi Alex.

To add to the above,  #table is the index before a  nil , but not necessarily the first one, so in the presence of holes you could end up encountering others in between. (ipairs(), on the other hand, does stop at the first nil , though this would break if Corona adopted newer flavors of Lua.) This seems like an odd design, but it’s more the case that, when a table is treated as an array, the “proper” behavior falls out of it, so it was convenient to expose it; break the contract and it’s a crapshoot.

table.maxn() does a brute-force review of the table, yes. This is of the underlying keys, though, which include the integers. If you had something like 

local t = { 3, 23, 3, 23, 1 } t[324242] = 2

and tried to count t , it wouldn’t need to iterate over the 324236 missing entries.

The situation where you need to be able to remove elements while keeping other elements’ indices intact is essentially what my Stable Array plugin addresses, in case that’s of interest. It also has an iterator. (Apologies for its rather rambling description. The bit about “cycles” in particular does a disservice to Lua’s garbage collector, which handles them fine except in certain circumstances involving weak tables.)