Struggling with Lua table

Hello All - just discovered Corona and quite intrigued by it and have started through the tutorials.

I have a C/VB/Java/Pascal background … and understand Arrays, Hashtables, Vectors etc However, I’m struggling to understand how the following piece of code is working. It is from the Bullet sample app. In it they create a 7x8 set of sodacans:

for i = 1, 7 do  
 for j = 1, 8 do  
 cans[i] = display.newImage( "soda\_can.png", 190 + (i\*24), 220 - (j\*40) )  
 physics.addBody( cans[i], { density=0.2, friction=0.1, bounce=0.1} )  
 end  
end  

“cans” is a table. They iterate through two loops. In most languages, would have filled the cans table with a line as follows:

 cans[i,j] = display.newImage( "soda\_can.png", 190 + (i\*24), 220 - (j\*40) )  

However, they just reference the [i] index into the table.

How is it that through every iteration of the ‘j’ loop, its not overwriting the current ‘cans[i]’ value with the new assignment. Somehow, it seems to be adding to the table with every iteration

I’m guessing its some sort of behavior in Lua tables but I havent been able to quite figure it out.

Appreciate the help,

Chris [import]uid: 12082 topic_id: 4197 reply_id: 304197[/import]

As a matter of pure/raw Lua, I think you are correct and this may actually be a bug in the example.
In Lua, you would do multidimensional arrays with multiple brackets or possibly with table keys:

Double-bracket:

cans = {} -- initialize table  
for i = 1, 7 do  
 cans[i] = {} -- initialize 2nd dimension  
end  
  
cans[i][j] = some\_value  

Alternatively, you could try table-keys, but you have to be a little careful. In Lua, any first-class values are allowed to be keys to a table. This includes both tables and functions.

cans = {} -- initialize 1D table  
cans[{i,j}] = some\_value  

But I think the default behavior is to simply look at the table address as the hash and not the values itself. So either you need to make sure you reuse the exact table instance or you need a metamethod override that inspects and utilizes the contents of the table-key.
But back to the original example, I would speculate that if the example is not producing incorrect results, it is because the physics.addBody call is making a copy of the data internally and nothing cares about the contents of cans elsewhere in the code. Does anything else actually make use of the variable cans later in the code? If not, then, maybe this is what’s really going on:

for i = 1, 7 do  
 for j = 1, 8 do  
 local result = display.newImage( "soda\_can.png", 190 + (i\*24), 220 - (j\*40) )  
 physics.addBody( result, { density=0.2, friction=0.1, bounce=0.1} )  
 end  
end  

[import]uid: 7563 topic_id: 4197 reply_id: 13026[/import]

Thank you for that. I think you may be right in that your interpretation is what its doing, and I just wasnt able to make the connection until you pointed it out to me. It doesn’t really care about the previous value after the call to addBody. The full code sample app is here:

http://developer.anscamobile.com/content/bullet

I was trying to write an extension to this that would remove all the cans. Given the above, I no longer have a reference to all the cans, so will try refactor the code to use a multi dimensional table instead that I can loop through and remove cans later on.

Any insight why the below is not valid - it starts to paint the cans and then fails with "attempt to index field ‘?’ (a nil value)
" on the cans[i][j] line at the second iteration of i: [the i,j value below]

1 1  
1 2  
1 3  
1 4  
1 5  
1 6  
1 7  
1 8  
2 1  
Runtime error  
 /Users/cdutoit/Downloads/Bullet/main.lua:39: attempt to index field '?' (a nil value)  

And the actual program

local cans = { {} }  
local function setupCans()  
 for i = 1, 7 do  
 for j = 1, 8 do  
 print (i,j)  
 cans[i][j] = display.newImage( "soda\_can.png", 190 + (i\*24), 220 - (j\*40) )  
 physics.addBody( cans[i][j], { density=0.2, friction=0.1, bounce=0.1} )  
 end  
 end  
end  
  

Thanks for the assistance! [import]uid: 12082 topic_id: 4197 reply_id: 13069[/import]

It’s because of the the way cans was being declared. I haven’t seen that way of declaring a multi-dimensional array in Lua before so not sure if it’s supposed to work but doing it this way works:

[code]
local cans = {}
local function setupCans()
for i = 1, 7 do
cans[i] = {}
for j = 1, 8 do
print (i,j)
cans[i][j] = display.newImage( “soda_can.png”, 190 + (i*24), 220 - (j*40) )
physics.addBody( cans[i][j], { density=0.2, friction=0.1, bounce=0.1} )
end
end
end
[import]uid: 9064 topic_id: 4197 reply_id: 13076[/import]

Yes, sorry, my goof. I got lazy on the initialization. Similar to C, each new dimension needs to be initialized.

cans = {}  
for i = 1, 7 do  
 cans[i] = {}  
end  

(edited in original response to avoid confusing other people) [import]uid: 7563 topic_id: 4197 reply_id: 13077[/import]

Great thanks bherrron and ewing, I now have it working thanks to the explanations above. [import]uid: 12082 topic_id: 4197 reply_id: 13357[/import]