memory of a dream
memory of a dream

Reputation: 1267

insert table values with string keys into Lua table

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?

Upvotes: 4

Views: 12498

Answers (2)

Seagull
Seagull

Reputation: 13859

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.

Upvotes: 2

Tom Blodget
Tom Blodget

Reputation: 20772

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}
}

Upvotes: 3

Related Questions