I started learning Lua recently, as far as I can tell, when I don't specify the index, the function table.insert
tries to put the value in the first nil in the table.
Why then is it that in table t
the 10
ends up at index 4, in table y
the 10
ends up at index 2, and in table x
it ends up at index 5
?
local t = {1, nil, 2}
table.insert(t,10)
for i = 1, 6 do
print(string.format("t[%d] = %s", i, t[i]))
end
print()
local y = {1, nil, 2}
y[5]= 3
table.insert(y, 10)
for i = 1, 6 do
print(string.format("y[%d] = %s", i, y[i]))
end
print()
local x = {1, nil, 2}
table.insert(x,2,20)
x[6]= 3
table.insert(x,10)
for i = 1, 6 do
print(string.format("x[%d] = %s", i, x[i]))
end
Terminal result:
t[1] = 1
t[2] = nil
t[3] = 2
t[4] = 10
t[5] = nil
t[6] = nil
y[1] = 1
y[2] = 10
y[3] = 2
y[4] = nil
y[5] = 3
y[6] = nil
x[1] = 1
x[2] = 20
x[3] = nil
x[4] = 2
x[5] = 10
x[6] = 3
I started learning Lua recently, as far as I can tell, when I don't specify the index, the function table.insert
tries to put the value in the first nil in the table.
Why then is it that in table t
the 10
ends up at index 4, in table y
the 10
ends up at index 2, and in table x
it ends up at index 5
?
local t = {1, nil, 2}
table.insert(t,10)
for i = 1, 6 do
print(string.format("t[%d] = %s", i, t[i]))
end
print()
local y = {1, nil, 2}
y[5]= 3
table.insert(y, 10)
for i = 1, 6 do
print(string.format("y[%d] = %s", i, y[i]))
end
print()
local x = {1, nil, 2}
table.insert(x,2,20)
x[6]= 3
table.insert(x,10)
for i = 1, 6 do
print(string.format("x[%d] = %s", i, x[i]))
end
Terminal result:
t[1] = 1
t[2] = nil
t[3] = 2
t[4] = 10
t[5] = nil
t[6] = nil
y[1] = 1
y[2] = 10
y[3] = 2
y[4] = nil
y[5] = 3
y[6] = nil
x[1] = 1
x[2] = 20
x[3] = nil
x[4] = 2
x[5] = 10
x[6] = 3
Share
Improve this question
edited Jan 30 at 0:11
Oka
26.4k6 gold badges48 silver badges56 bronze badges
asked Jan 29 at 23:40
RafaelRafael
311 silver badge2 bronze badges
1 Answer
Reset to default 3From table.insert
, we can see that table.insert(t, 42)
behaves as
t[#t + 1] = 42
From 3.4.7 – The Length Operator:
The length operator applied on a table returns a border in that table. A border in a table t is any non-negative integer that satisfies the following condition:
(border == 0 or t[border] ~= nil) and (t[border + 1] == nil or border == math.maxinteger)
[ ... ]
A table with exactly one border is called a sequence.
[ ... ]
When t is a sequence, #t returns its only border, which corresponds to the intuitive notion of the length of the sequence. When t is not a sequence, #t can return any of its borders. (The exact one depends on details of the internal representation of the table, which in turn can depend on how the table was populated and the memory addresses of its non-numeric keys.)
In other words, calling table.insert
on tables with multiple borders, without specifying a position, will insert the value at an index determined by the internal representation of the table.
Avoid this if portability is a concern. For example, on my system, the results of your program differ between the reference implementation of Lua and LuaJIT.
$ lua -v
Lua 5.4.6 Copyright (C) 1994-2023 Lua., PUC-Rio
$ luajit -v
LuaJIT 2.1.1734355927 -- Copyright (C) 2005-2023 Mike Pall. https://luajit./
$ diff <(lua example.lua) <(luajit example.lua)
2c2
< t[2] = nil
---
> t[2] = 10
4c4
< t[4] = 10
---
> t[4] = nil
17,19c17,19
< x[3] = nil
< x[4] = 2
< x[5] = 10
---
> x[3] = 2
> x[4] = 10
> x[5] = nil