You linked the information you need for your answer.
A border in Lua 5.3 is defined as:
(border == 0 or t[border] ~= nil) and t[border + 1] == nil
A proper sequence can only contain one border. However to cover some other condition the code does require a bit more leg work, such as validating the index can be in a sequence.
function is_sequence(t)
local borders = 0
if t[1] ~= nil then -- all sequences must start at 1.
for index in pairs(t) do
if natural_index(index) and t[index + 1] == nil then
borders = borders + 1
if borders > 1 then
break
end
end
end
end
return borders == 1 or valid_no_borders(t) and borders == 0
end
function natural_index(index)
return type(index) == "number" and index > 0 and math.floor(index) == index
end
function valid_no_borders(t)
result = true
for k in pairs(t) do
if natural_index(k) then
result = false
break
end
end
return t[1] == nil and result
end
-- Tests
local seqs = {
{ 1, 2, 3, 4, 5 }, -- obviously, it's a sequence.
{ 1, 2, 3, 4, ["potato"] = 5 },
{ 1, 2, [3.3] = 3 },
{ [2.2] = 2 },
{ [-1] = -1, [0] = 0, 1, 2, 3 },
{},
}
for _, v in ipairs(seqs) do
print("seq: ", is_sequence(v))
end
local non_seqs ={
{ 1, 2, 3, nil, 5 }, -- but it's not.
{ [2] = 2 },
}
for _, v in ipairs(non_seqs) do
print("non_seq: ", is_sequence(v))
end
Results
seq: true
seq: true
seq: true
seq: true
seq: true
seq: true
non_seq: false
non_seq: false
This method has the benefit of only evaluating each element once and exiting as early as possible if the table is not a valid sequence.