Lua tables can be used to create any Abstract Data Structure, in your case you indicated that you want a "list". A Lua table is a data structure that combines numeric index based access with key:value access.
Based on your example, you are using the numeric index feature of tables that let you iterate (with ipairs()) through those values. You will not be able to put nil into the table since the numeric index stops at the first nil entry. The remaining values in the table are stored as key:value pairs.
There are several work-arounds, but it depends on why you want a nil in the list. The simplest approach is to use the string "nil" rather than the native data type nil.
a = {1, 2, 3, "nil", 4}
for k,v in ipairs(a) do
print(k,v)
end
The result of this code is:
1 1
2 2
3 3
4 nil
5 4
Because of the way Lua implements strings, there is not a performance penalty for comparing to the string "nil" versus comparing to the native type nil.
The issue of "holes" (caused by nil) in an array are discussed in Programming in Lua, Chapter 5 Tables. Roberto Ierusalimschy recommendation is to track the size of the array to avoid problems with holes.
The following code shows an Object Oriented approach to tracking the size of the list. There are many possible variations on this theme.
function makeList(...)
local list = table.pack(...)
list.length =
function(self) return self.n
end
list.append =
function(self, value)
self.n = self.n + 1
self[self.n] = value
end
list.print =
function(self)
for i = 1, self.n do print(i, self[i]) end
end
return list
end
a = makeList(1, 2, 3, nil, 4)
a:append(5)
a:print()
print(a:length())
The result is:
1 1
2 2
3 3
4 nil
5 4
6 5
6
Note that the function table.pack creates a field 'n' which contains the correct number of items even when 'nil' is present. See PIL chapter 6.2, Variadic Functions for a complete explanation.