9

テーブル引数が真の配列かどうかを判断する関数を作成するにはどうすればよいですか?

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

数字キーが唯一のキーかどうかを調べる方法がわかりません。

4

7 に答える 7

20

編集:これは、最近発見した配列をテストする新しい方法です。によって返される各要素についてpairs、n 番目の項目が ではないことを単純にチェックしますnil。私の知る限り、これはarray-nessをテストする最も速くてエレガントな方法です。

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-21T07:22:41.357 に答える
4

ipairs はインデックス 1..n を反復処理します。ここで、n+1 はnil 値 ペアを持つ最初の整数インデックスであり、すべてのキーを反復処理します。 シーケンシャル インデックスよりも多くのキーがある場合、配列にすることはできません。

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-22T18:25:34.243 に答える
2

「真の配列」とは、キーが数字のみのテーブルを意味すると思います。これを行うには、テーブルのすべてのキーのタイプを確認します。これを試して :

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-20T20:09:15.903 に答える
1

注: @eric が指摘するように、ペアは特定の順序で反復するように定義されていません。したがって、これは有効な答えではありません。

以下で十分です。キーが 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-26T23:32:35.257 に答える
0

これについての私の#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-04T14:20:22.090 に答える
0

私は最近、別の同様の質問に対してこのコードを書きました:

---Checks if a table is used as an array. That is: the keys start with one and are sequential numbers
-- @param t table
-- @return nil,error string if t is not a table
-- @return true/false if t is an array/isn't an array
-- NOTE: it returns true for an empty table
function isArray(t)
    if type(t)~="table" then return nil,"Argument is not a table! It is: "..type(t) end
    --check if all the table keys are numerical and count their number
    local count=0
    for k,v in pairs(t) do
        if type(k)~="number" then return false else count=count+1 end
    end
    --all keys are numerical. now let's see if they are sequential and start with 1
    for i=1,count do
        --Hint: the VALUE might be "nil", in that case "not t[i]" isn't enough, that's why we check the type
        if not t[i] and type(t[i])~="nil" then return false end
    end
    return true
end
于 2011-09-23T15:05:16.773 に答える
-1

0 から要素の数まで繰り返し、カウンターのインデックスを持つすべての要素が存在するかどうかを確認します。配列でない場合、一部のインデックスがシーケンスで欠落します。

于 2011-05-20T20:05:48.553 に答える