4

I'm relatively new to the Lua language and there's something I'm obviously missing about table structures.

I'm trying to create a table of tables, with each table in the table having a key and the value being the respective table.

Ok, that statement can be confusing. Here's an example:

{{ key = "RC", value = {1, 2, 3, 4}},
 { key = "M",  value = {4, 8, 7}},
 { key = "D",  value = {3, 8, 9}}
 ...}

for this I used the following algorithm:

local listOfLists = {};
...
if condition1 then
   listOfLists[key1] = list1;
end
...
if condition2 then
   listOfLists[key2] = list2;
end
...

And so on...

I hope to use the keys to later determine which lists have been added to the table. But the thing is, no lists seem to be added to the table even if all the conditions are met.

I can use table.insert(listOfLists, list1) in place of listOfLists[key1] = list1 but then I won't be able to tell which lists were added to the collection. Ant suggestions?

3
  • Note that the example you have provided satisfies listOfLists[key1] = list1 for key1 an integer and list1 of the form {key="R", value={1,2,3,..}}. A more practical structure might be, depending on your requirements, { RC = {1,2,3,...}, M = {4,8,7}, ... }, i.e. where key1 is the key of original list1, and list1 is the value table. Can you print what is key1 and list1 when the condition1 is met? Do print("key", type(key1), key1, "list", type(list1), list1). Commented Mar 24, 2014 at 0:38
  • I explicitly stated "key" and "value" in order to provide clarity, but it seems I added confusion instead. What I'm trying to build is exactly what you described described in your comment { RC = {1,2,3,...}, M = {4,8,7}, ... } with no success though. Commented Mar 24, 2014 at 12:04
  • OK, well then I doubt the answers you got will help solve "no lists are ever added to the table even if all the conditions are met", what is status so far? If not, I think you will have to post more detailed code showing the structure you have, the actual conditions, and adding items to list, because what you are showing looks fine as is, so the problem is in code not shown. Commented Mar 24, 2014 at 13:24

2 Answers 2

3

Lua tables are a flexible data structure. Elements are key-value pairs. A key is any Lua value except nil. A value can have any value except nil. Assigning nil to the value obliterates the pair.

The (possibly empty) subset of a table that has key values of the number type that are integers from 1 to n is called a sequence. n is determined as the last such key that is paired with a nil value. Several table functions and operators work only with sequences.

Table constructors allow several syntaxes for keys:

  1. Implied via a sequence: {1, 2, 3}
  2. Explicit keys: {[1] = 1, [3] = 3, ["two"] = "value"}
  3. Identifier keys: {one = 1, two = 2}

A table constructor can use any combination of them.

You have defined a sequence of elements, each of which is a table with two elements, the second of which is a sequence.

It appears you want keys to be strings and values to be sequences:

{ 
  RC = {1, 2, 3, 4},
  M = {4, 8, 7},
  D = {3, 8, 9}
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks Tom, you explained it much more clearly than me. That's what I want but unfortunately I am unable to achieve that. From what I read on the Lua.org I would expect that local listOfLists = {}; and listOfLists["RC"] = {1, 2, 3, 4}; would generate something like { RC = {1, 2, 3, 4}}, but the listOfLists table is still {} after the operation. table.maxn(listOfLists) return 0
maxn should return 0 in that case because you haven't any keys of type number that are positive integers. The only key is the string "RC". Try table.maxn(listOfLists.RC); It should be 4.
2

It's hard to understand, what do you wanna achieve. So, if you want more specific answer, provide more info.

You can create associative table of tables.

local map = {}
map["key"] = { 1, 2, 3, 4 }
print(map.key[3])

Or you can create an array of tables

local vector = {}
vector[1] = { 1, 2, 3, 4 }
print(vector[1][2])

Or you can combine approaches.

To create

{{ key = "RC", value = {1, 2, 3, 4}},
{ key = "M",  value = {4, 8, 7}},
{ key = "D",  value = {3, 8, 9}}
...}

You can use table constructor or smth from code.

local tbl = { { key = "RC", value = {1, 2, 3, 4}} } -- init first elem from constructor
table.insert(tbl, { key = "M", value = {4, 8, 7}}) -- table insert & constructor
tbl[2] = {} -- Array-based access.
tbl[2].key = "D" --key access
tbl[2]["value"] = { 3, 8, 9 } -- other way

Note, that each table consists of two parts: vector for sequental keys from 1 to N, and map otherwise. Some functions, like table length operator or ipairs iterator are guaranteed to work only with vector-part of table. But they are significantly faster.

EDIT: (last paragraph explanation)

If you have a table with some keys and want to iterate through, you can use ipairs or pairs.

ipairs is ordered, and goes from 1 to first not-nil element. It doesn't iterate over not-integer keys. pairs goes trough any key, but doesn't guarantee order.

local map = { 1, 2, 3, key = 6, [5] = 5 }
for i, v in ipairs(map) do
  print(v) -- will output 1, 2, 3. first nil element is map[4]. map[5] will mot be visited.
end

for i, v in pairs(map) do -- NOTE pairs usage
  print(v) -- will output 1, 2, 3, 5, 6 in ANY order
end

map[4] = 4 -- Fill gap
for i, v in ipairs(map) do
   print(v) -- will output 1, 2, 3, 4, 5. Now first nil element is map[6]
end

Length operator works similar to ipairs, it doesn't count elements not visited by ipairs method.

table.maxn works with numerical indices, and will return zero for your table. Reference say that table.maxn

Returns the largest positive numerical index of the given table, or zero if the table has no positive numerical indices. (To do its job this function does a linear traversal of the whole table.)

Little example about length and table.maxn

local a = { 1, 2, 3, [5] = 5}
print(table.maxn(a)) -- 5
print(#a) -- 3
a = { key = 4 } 
print(table.maxn(a)) -- 0
print(#a) -- 0
print(a["key"]) -- 4, nothing is lost
local num = 0
for _, __ in pairs(a) do num = num + 1 end
print(num) -- 1 We find it.

6 Comments

And also the possible solution of having { RC = {1, 2, 3, 4}, ... }
It's something similar to your first example, but aster doing map["key"] = { 1, 2, 3, 4 }, print(table.maxn(map)); returns 0 and for key, value in ipairs(maxn) do ... end also doesn't enter the loop. I'm not sure what I'm doing wrong. Btw. the key can be any string, and the list of numbers (basically a list of identifiers) is never empty when I add it to the "map"
@memoryofadream ipairs goes only by number indexed elements. from 1 to first not-nil element. I'll add more explanation in answer in 5 minutes.
@memoryofadream Expanded the answer. Look at EDITED part, and especially last code example. Hope it's clearer now.
@Seagull thanks for the detailed information. I'll let you know how it turns out in about 4-5 hours.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.