Reputation: 3044
I'm a beginner in Lua.
I thought pushing values to a table using string keys would automatically also do number indexing but I think I was wrong about this.
My Code :
local t = {}
t.name = "John"
t.age = 30
print("Name : " .. t.name .. "\nAge : " .. t.age)
While this code works fine and prints the expected result,
Name : John
Age : 30
If I try to print the result this way,
print("Name : " .. t[1] .. "\nAge : " .. t[2])
I get the following error:
lua: main.lua:5: attempt to concatenate a nil value (field '?')
stack traceback:
main.lua:5: in main chunk
[C]: in ?
Does this mean I cannot iterate through the table using for
with number indexing without having to know the key strings?
If so, is there any work around to make the both way work?
Upvotes: 2
Views: 5236
Reputation: 10939
You can hack yourself a numeric index using a metatable, but the that will be completely useless because in a table with non-numeric, non-consecutive indices the order is unspecified.
local mt = { __index = function(t, n)
assert(n > 0)
for k, v in pairs(t) do
n = n - 1
if n == 0 then
return v
end
end
end }
local t = {}
setmetatable(t, mt)
t.name = "John"
t.age = 30
print("Name : " .. t.name .. "\nAge : " .. t.age)
print("Name : " .. t[1] .. "\nAge : " .. t[2])
Executing the above script several times in a row will reveal the problem:
$ lua test.lua
Name : John
Age : 30
Name : John
Age : 30
$ lua test.lua
Name : John
Age : 30
Name : 30
Age : John
Upvotes: 1
Reputation: 15313
Adding values to a table does not also add them as with index keys as well. When you go to use the values in your table you can access them either using the dot notation, as in your first example, or like this:
print("Name : " .. t["name"] .. "\nAge : " .. t["age"])
You can iterate over the key value pairs in the table using the function pairs
like so:
for k, v in pairs(t) do
print(k, v)
end
If you want to use indexes instead of strings keys, you can set it up like this:
local t = {
"John",
30,
}
print("Name : " .. t[1].. "\nAge : " .. t[2])
When you do it this way, the values in the table t
have integer indexes automatically assigned to each value. If you want to iterate over them one by one, you can iterate with ipairs:
for i, v in ipairs(t) do
print(i, v)
end
Upvotes: 3