3

Can someone explain this apparent insanity?

> t = {1, 2, 3} -- Table length 3. Simple
> = #t
3  -- Yep

> t[3] = nil -- Remove the last element?
> = #t
2 -- Ok it realises it is the last one (since #t = 3) and decrements the length

> t[6] = 6 -- Add a separate element?
> = #t
2 -- Ok... I guess? Although surely it knew #t = 2, and so now #t should be 6?

> t[4] = 4 -- Add another separate element
> = #t
4 -- Errr... what.

> t[5] = 5 -- Append another element
> = #t
6 -- Ok now it remembers element 6? Wtf?

Ok let me try again...

> t = {1, 2, 3}
> = #t
3
> t[10] = 10
> = #t
3
> t[4] = 4
> = #t
4
> t[9] = 9
> = #t
4
> t[8] = 8
> = #t
10

What.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
Timmmm
  • 88,195
  • 71
  • 364
  • 509
  • Ah yeah that explains it. I don't know why they couldn't have #t return nil or -1 for the undefined cases. – Timmmm Apr 25 '16 at 18:13
  • You could implement your own `__len` metamethod to return a different result for non-sequence tables, but you would still have to identify if a table is a proper sequence or not. – Adam Apr 25 '16 at 18:17

1 Answers1

5

The length of a table is only defined if the table is a proper sequence (consecutive integer keys).

The Lua manual explains the length operator:

Unless a __len metamethod is given, the length of a table t is only defined if the table is a sequence, that is, the set of its positive numeric keys is equal to {1..n} for some non-negative integer n. In that case, n is its length. Note that a table like

{10, 20, nil, 40}

is not a sequence, because it has the key 4 but does not have the key 3. (So, there is no n such that the set {1..n} is equal to the set of positive numeric keys of that table.) Note, however, that non-numeric keys do not interfere with whether a table is a sequence.

Adam
  • 3,053
  • 2
  • 26
  • 29