Corona / LUA array structure question

I am trying to build an array with columns and variable number of rows. I want to be able to initialize the first element, and add many more (50 or so) at runtime. The problem is how to reference the array elements at runtime. 

testArray = {

    {col1 = “”},

    {col2 = “”},

    {col3 = “”},

    {col4 = “”}

}

testArray[1].col1 = “testing 1”

testArray[2].col1 = “testing 2”

testArray[3].col1 = “testing 3”

testArray[4].col1 = “testing 4”

What am I doing wrong?

testArray[1].col1 = “testing 1”

testArray[2].col2 = “testing 2”

testArray[3].col3 = “testing 3”

testArray[4].col4 = “testing 4”

:wink:

Actually, that sorta works, but not really…

What I need is something like a spreadsheet, with several addressable columns, and 50 vertical rows of data.

– define variables

testArray = {

    {col1 = “”},

    {col2 = “”},

    {col3 = “”}

}

testArray[1].col1 = “testing row 1, col 1”

testArray[1].col2 = “testing row 1, col 2”

testArray[1].col3 = “testing row 1, col 3”

testArray[2].col1 = “testing row 2, col 1”

testArray[2].col2 = “testing row 2, col 2”

testArray[2].col3 = “testing row 2, col 3”

testArray[3].col1 = “testing row 3, col 1”

testArray[3].col2 = “testing row 3, col 2”

testArray[3].col3 = “testing row 3, col 3”

testArray[4].col1 = “testing row 4, col 1”   – error: attempt to index field ‘?’ (a nil value)

testArray[4].col2 = “testing row 4, col 2”

testArray[4].col3 = “testing row 4, col 3”

As defined, it thinks there are three columns, and appears to reuse the row index until it gets to 4 where it dies with this error: attempt to index field ‘?’ (a nil value)

Perhaps this :

NUMBER\_OF\_ROWS=50 NUMBER\_OF\_COLS=10 for row=1,NUMBER\_OF\_ROWS do testArray[row]={} for col=1,NUMBER\_OF\_COLS do testArray[row][col]="testing row "..tostring(row)..", col "..tostring(col) end end

I understand multi-dimensional arrays and that seems to work, but I was trying to use the named columns that I had seen before somewhere. Apparently I am leaving something off…

I could simply declare names as a variable and use them for the col offset.

local col1 = 1

local col2 = 2

local col3 = 3

and then reference them with:

testArray[row][col1] = “testing rowx - col1”

since there isn’t a constant option in lua, it has to be less efficient than interpreting it in the compiler once, versus interpreting the col1 value as a variable which could be anything.

If I don’t get this figured out soon, I’ll just use a database for the array and wipe it out before each use. I assume the overhead is about the same… Both are in memory after all.

You’re not quite setting up the initial table right. Currently you’re setting up an array of 3, testArray[1] contains col1, testArray[2] contains col2, and testArray[3] contains col3. Because testArray[4] doesn’t exist you get an error trying to set testArray[4].col1 etc.

[lua]

local rows = 4

local testArray = {}

for a = 1, rows, 1 do

  testArray[a] = {col1 = “”, col2 = “”, col3 = “”}

end

testArray[4].col1 = “test row 4 column 1”

[/lua]

If I don’t treat it as named array columns, that works. 

I can create an array with any reasonable number of rows or columns.

I was trying to use the named column option since it makes sense to me that the compiler can resolve it at compile time and produce more efficient code than having to resolve and x/y array pointer from two separate variables.

I was hoping that an unnamed genius could shed light on how Lua / Corona wants us to do it…

I’m already headed toward making a sqlite database instead of an array. I don’t know what the impact will be on performance but we will see once I get it working… so, I may be back :slight_smile:

Thanks for all who stabbed at the problem!

Stu

It’s still not really clear what you’re trying to achieve.

If you want to add to an array at runtime, you just do:

[lua]

testArray[#testArray+1] = {col1 = “”, col2 = “”, col3 = “”}   – adds an extra row with three default columns

testArray[#testArray].col4 = “”  – adds an extra column to the new row

[/lua]

I was trying to get the column headers to be named and use the row offset to select a row.

testArray[x].col2 = “col2”

print (testArray[x].col2)

Well you can call the columns Nigel, Steve and Frank for all Lua cares.

If you want to address a column by name:

[lua]

print (testArray[x].columnName)

– or

print (testArray[x][“columnName”])

[/lua]

To address a column by a name held in a string:

[lua]

local col1 = “firstName”

print (testArray[x][col1])

[/lua]

you must first create a row before you can access it.

for example, if given this as a starting condition:

local t = { { a=1, b=2, c=3 }, { a=2, b=3, c=4 } }

then the following assignments will work:

t[1].d = 1234567 t[2].d = 2345678

because both rows t[1] and t[2] already exist as tables, and new keys (“d”) can be created within those row tables.

however the following assignment will NOT work:

t[3].d = 3456789

because row 3 does NOT yet exist, so trying to access key “d” in a non-existent table is an error.

instead you must first create row 3, THEN assign to “d”, as follows:

t[3] = {} t[3].d = 3456789

testArray[1].col1 = “testing 1”

testArray[2].col2 = “testing 2”

testArray[3].col3 = “testing 3”

testArray[4].col4 = “testing 4”

:wink:

Actually, that sorta works, but not really…

What I need is something like a spreadsheet, with several addressable columns, and 50 vertical rows of data.

– define variables

testArray = {

    {col1 = “”},

    {col2 = “”},

    {col3 = “”}

}

testArray[1].col1 = “testing row 1, col 1”

testArray[1].col2 = “testing row 1, col 2”

testArray[1].col3 = “testing row 1, col 3”

testArray[2].col1 = “testing row 2, col 1”

testArray[2].col2 = “testing row 2, col 2”

testArray[2].col3 = “testing row 2, col 3”

testArray[3].col1 = “testing row 3, col 1”

testArray[3].col2 = “testing row 3, col 2”

testArray[3].col3 = “testing row 3, col 3”

testArray[4].col1 = “testing row 4, col 1”   – error: attempt to index field ‘?’ (a nil value)

testArray[4].col2 = “testing row 4, col 2”

testArray[4].col3 = “testing row 4, col 3”

As defined, it thinks there are three columns, and appears to reuse the row index until it gets to 4 where it dies with this error: attempt to index field ‘?’ (a nil value)

Perhaps this :

NUMBER\_OF\_ROWS=50 NUMBER\_OF\_COLS=10 for row=1,NUMBER\_OF\_ROWS do testArray[row]={} for col=1,NUMBER\_OF\_COLS do testArray[row][col]="testing row "..tostring(row)..", col "..tostring(col) end end

I understand multi-dimensional arrays and that seems to work, but I was trying to use the named columns that I had seen before somewhere. Apparently I am leaving something off…

I could simply declare names as a variable and use them for the col offset.

local col1 = 1

local col2 = 2

local col3 = 3

and then reference them with:

testArray[row][col1] = “testing rowx - col1”

since there isn’t a constant option in lua, it has to be less efficient than interpreting it in the compiler once, versus interpreting the col1 value as a variable which could be anything.

If I don’t get this figured out soon, I’ll just use a database for the array and wipe it out before each use. I assume the overhead is about the same… Both are in memory after all.

You’re not quite setting up the initial table right. Currently you’re setting up an array of 3, testArray[1] contains col1, testArray[2] contains col2, and testArray[3] contains col3. Because testArray[4] doesn’t exist you get an error trying to set testArray[4].col1 etc.

[lua]

local rows = 4

local testArray = {}

for a = 1, rows, 1 do

  testArray[a] = {col1 = “”, col2 = “”, col3 = “”}

end

testArray[4].col1 = “test row 4 column 1”

[/lua]

If I don’t treat it as named array columns, that works. 

I can create an array with any reasonable number of rows or columns.

I was trying to use the named column option since it makes sense to me that the compiler can resolve it at compile time and produce more efficient code than having to resolve and x/y array pointer from two separate variables.

I was hoping that an unnamed genius could shed light on how Lua / Corona wants us to do it…

I’m already headed toward making a sqlite database instead of an array. I don’t know what the impact will be on performance but we will see once I get it working… so, I may be back :slight_smile:

Thanks for all who stabbed at the problem!

Stu

It’s still not really clear what you’re trying to achieve.

If you want to add to an array at runtime, you just do:

[lua]

testArray[#testArray+1] = {col1 = “”, col2 = “”, col3 = “”}   – adds an extra row with three default columns

testArray[#testArray].col4 = “”  – adds an extra column to the new row

[/lua]

I was trying to get the column headers to be named and use the row offset to select a row.

testArray[x].col2 = “col2”

print (testArray[x].col2)

Well you can call the columns Nigel, Steve and Frank for all Lua cares.

If you want to address a column by name:

[lua]

print (testArray[x].columnName)

– or

print (testArray[x][“columnName”])

[/lua]

To address a column by a name held in a string:

[lua]

local col1 = “firstName”

print (testArray[x][col1])

[/lua]