As I understand Lua, an array is just a table where the keys start at 1 and increment sequentially. However, there are features within Lua to manipulate arrays in the traditional sense (e.g. ipairs, square-bracket syntax, etc.). So Lua does "support" the concept of arrays.
In Lua, you could initialize an array like this:
-- Code Example "A"
a={}
a[1] = "abc"
a[2] = "xyz"
a[3] = "foo"
That works, but is sometimes abbreviated as follows:
-- Code Example "B"
a={ "abc", "xyz", "foo" }
This also works and is equivalent to example "A". Furthermore, Lua also provides a way to initialize an an array by specifying each index, as follows:
-- Code Example "C"
a={
[1] = "abc",
[2] = "xyz",
[3] = "foo"
}
The above syntax should have identical semantics to examples "A" and "B". However, example "C" suffers from an insidious problem, which examples "A" and "B" do not suffer from. In particular, given the variable "a" from example "C" , you can't use the normal Lua design-pattern to determine that "a" can be treated as an array (as opposed to a table). The well-known Lua pattern for determining if a table is an array is as follows:
table_is_array = (type(a)== "table") and (#a>0) and (next(a,#a)==nil)
In particular, the expression next(a,#a) returns a value of nil for code examples "A" and "B" (which is correct to indicate an array), while the expression next(a,#a) returns a value of 1 for code example "C" (which is incorrect for an array). The question is, why are semantically identical array initialization syntaxes producing different results with the Lua "next" function? Clearly all the code examples "A", "B", and "C" are all doing exactly the same thing, but yet they produce different results with the Lua "next" function. Worse, the differing results interfere with the most common way to determine if a table can be treated as an array in Lua.
So to recap:
a={}
a[1] = "abc"
a[2] = "xyz"
a[3] = "foo"
t={
[1] = "abc",
[2] = "xyz",
[3] = "foo"
}
print("next(a,#a) = " .. tostring(next(a,#a))) -- displays nil (correct)
print("next(t,#t) = " .. tostring(next(t,#t))) -- displays 1 (incorrect)
I need to initialize the table as in example C because in my code, the index values are in variables, similar to this example:
i_abc=1
i_xyz=2
i_foo=3
v_abc="abc"
v_xyz="xyz"
v_foo="foo"
-- Now put the above data into an array
a={
[i_abc] = v_abc,
[i_xyz] = v_xyz,
[i_foo] = v_foo
}
Why does the array-checking pattern fail for example C?