2

so I was trying to test how table.insert functions when there is already an entry, and I found the behaviour that if there is an entry on a multiple of 4 prior to inserting anything into the table that is before that entry, it messes up

t = {}
t[4] = "this works"
for i = 1,9 do
table.insert(t,i)
end
for i = 1,#t do
print(t[i])
end
print("total: "..#t)

output:

1
2
nil
this works
3
4
5
6
7
8
9
total: 11
user5888870
  • 21
  • 1
  • 2
  • 1
    Possible duplicate of [An Interesting phenomenon of Lua's table](http://stackoverflow.com/questions/16076364/an-interesting-phenomenon-of-luas-table) – hjpotter92 Sep 17 '16 at 06:17

1 Answers1

4

It happens because table.insert by default inserts elements at the position #list+1, but the length operator is only defined for sequences and the table with gaps (as in your case nil, nil, nil, "this works" or 1, nil, nil, "this works" or 1, 2, nil, "this works") is not a sequence.

You can get a bit more expected result if you use table.insert(t, i, i), as this will explicitly specify where the elements need to be inserted (instead of relying on the length operator), but the insertion will still be affected by nil elements in the table. If you do this, after 4 insertions you may get {1, 2, 3, 4, "this works"} and after 5 insertions you may get {1, 2, 3, 4, 5, "this works"}, which may or may not be what you need.

(To specifically answer your question about multiples of 4: the length operator is using binary search, which also depends on the number of elements already stored in the array part of the table. When you have 1, 2, nil, 4, the algorithms finds 2 and then finds 4, which satisfies the criterion for the length value for sequences (n value is not nil, but n+1 value is), so it returns 4 and the next element is inserted at the position 5 and not 3 as you'd probably expect.)

Paul Kulchenko
  • 25,884
  • 3
  • 38
  • 56
  • for t[3] and t[5] = "this works" I have no nil entries with the example I provided – user5888870 Sep 17 '16 at 06:16
  • @user5888870, I updated the answer with details on multiples of 4. t[3] and t[5] work because in the first case after two insertions, #t == 3 and in the second case #t = 5 after four insertions (so the table content becomes a proper sequence in both cases). – Paul Kulchenko Sep 17 '16 at 06:22