如何检查Lua表是否仅包含连续的数字索引?

如何编写一个函数以确定它的表参数是否为真正的数组?

isArray({1, 2, 4, 8, 16}) -> true
isArray({1, "two", 3, 4, 5}) -> true
isArray({1, [3]="two", [2]=3, 4, 5}) -> true
isArray({1, dictionaryKey = "not an array", 3, 4, 5}) -> false

我看不出任何方法可以找出数字键是否是惟一键的方法。

原文链接 https://stackoverflow.com/questions/6077006

点赞
stackoverflow用户693716
stackoverflow用户693716

从0到元素数量迭代,并检查计数器索引的所有元素是否存在。如果它不是一个数组,则序列中将缺失一些索引。

2011-05-20 20:05:48
stackoverflow用户20043
stackoverflow用户20043

将下面翻译成中文并且保留原本的 markdown 格式


By "true array", I suppose you mean a table whose keys are only numbers. To do this, check the type of every key of your table. Try this :

当你说 "真正的数组" 的时候,我想你是指仅由数字作为键名的表格。为了实现这个,我们需要检查表格中每个键名的类型。请尝试以下代码片段:

function isArray(array)
    for k, _ in pairs(array) do
        if type(k) ~= "number" then
            return false
        end
    end
    return true --Found nothing but numbers !
end
2011-05-20 20:09:15
stackoverflow用户312586
stackoverflow用户312586

以下是新的测试数组方法,我最近刚刚发现的。对于每个由 pairs 返回的元素,它只需检查它的第n项不是 nil。据我所知,这是测试数组最快、最简洁的方法。

local function isArray(t)
  local i = 0
  for _ in pairs(t) do
    i = i + 1
    if t[i] == nil then return false end
  end
  return true
end
2011-05-21 07:22:41
stackoverflow用户216292
stackoverflow用户216292

ipairs迭代了1到n的索引,其中n+1是第一个具有nil值的整数索引。

pairs迭代所有键。

如果键比顺序索引多,则它不能是一个数组。

所以,你所要做的就是看pairs(table)中元素的数量是否等于ipairs(table)中元素的数量。

代码可以写成如下形式:

function isArray(tbl)
    local numKeys = 0
    for _, _ in pairs(tbl) do
        numKeys = numKeys+1
    end
    local numIndices = 0
    for _, _ in ipairs(tbl) do
        numIndices = numIndices+1
    end
    return numKeys == numIndices
end

我对Lua还很陌生,所以可能有一些内置函数可以简化numKeys和numIndices的计算。

2011-05-22 18:25:34
stackoverflow用户596285
stackoverflow用户596285

以下是我的解释,使用 #array 来检测有间断或者过多的键被读取:

function isArray(array)
  local count=0
  for k,_ in pairs(array) do
    count=count+1
    if (type(k) ~= "number" or k < 1 or k > #array or count > #array or math.floor(k) ~= k) then
      return false
    end
  end
  if count ~= #array then
    return false
  end
  return true
end
2011-07-04 14:20:22
stackoverflow用户796584
stackoverflow用户796584

我最近为另一个类似的问题编写了这段代码:

--- 检查表是否用作数组。也就是说:键以一个开始并且是连续的数字
-- @param t 表格
-- @return 如果t不是表,则为nil,error字符串。
-- @return 如果t是数组/不是数组,则为true/false
-- 注意:对于空表,它返回true
function isArray(t)
    if type(t)~="table" then return nil,"Argument is not a table! It is: "..type(t) end
    -- 检查所有表键是否是数字,并计算它们的数量
    local count=0
    for k,v in pairs(t) do
        if type(k)~="number" then return false else count=count+1 end
    end
    -- 所有键都是数字。现在看看它们是否是连续的并且以1开始
    for i=1,count do
        -- 提示:值可能为“nil”,在这种情况下,“not t[i]”不够,因此我们需要检查类型
        if not t[i] and type(t[i])~="nil" then return false end
    end
    return true
end
2011-09-23 15:05:16
stackoverflow用户790981
stackoverflow用户790981

注:正如@eric指出的,pairs没有定义按特定顺序迭代。 因此这不是一个有效的答案。

以下应该足够; 它检查键从1一直到末尾是否连续:

local function isArray(array)
  local n = 1
  for k, _ in pairs(array) do
    if k ~= n then return false end
    n = n + 1
  end

  return true
end
2012-10-26 23:32:35