web-dev-qa-db-ja.com

Luaのハッシュテーブルのキーの数を取得するにはどうすればよいですか?

myTable = {}
myTable["foo"] = 12
myTable["bar"] = "blah"
print(#myTable) -- this prints 0

キーの数を取得するために、実際にテーブルの項目を反復処理する必要がありますか?

numItems = 0
for k,v in pairs(myTable) do
    numItems = numItems + 1
end
print(numItems) -- this prints 2
42
Jay

#演算子とtable.getn()の両方を試しました。 table.getn()はあなたが望むことをするだろうと思っていましたが、結局それは#と同じ値、つまり0を返しています。辞書は必要に応じてnilプレースホルダーを挿入するようです。

キーをループして数えることが、辞書のサイズを取得する唯一の方法のようです。

21
Aaron Saarela

長さ演算子:

テーブルtの長さは、t [n]がnilではなく、t [n + 1]がnilになるような任意の整数インデックスnとして定義されます。さらに、t [1]がnilの場合、nはゼロにすることができます。 1から指定されたnまでのnil以外の値を持つ通常の配列の場合、その長さは、最後の値のインデックスであるnとまったく同じです。配列に「穴」(つまり、他の非nil値の間のnil値)がある場合、#tはnil値の直前にある任意のインデックスにすることができます(つまり、そのようなnil値を終わりと見なすことができます)配列の)。

したがって、長さを取得する唯一の方法はそれを反復することです。

7
serioys sam

手動でキーを反復処理する以外に、メタメソッドを介してキーを自動的に追跡するのは簡単です。作成したすべてのテーブルを追跡したくない場合を考えると、任意のテーブルをキーカウント可能なオブジェクトに変換できる関数を作成するだけで済みます。以下は完璧ではありませんが、要点を説明すると思います。

function CountedTable(x)
  assert(type(x) == 'table', 'bad parameter #1: must be table')

  local mt = {}
  -- `keys`  will represent the number of non integral indexes
  -- `indxs` will represent the number of integral indexes
  -- `all`   will represent the number of both 
  local keys, indxs, all = 0, 0, 0

  -- Do an initial count of current assets in table. 
  for k, v in pairs(x) do
    if (type(k) == 'number') and (k == math.floor(k)) then indxs = indxs + 1
    else keys = keys + 1 end

    all = all + 1
  end

  -- By using `__nexindex`, any time a new key is added, it will automatically be
  -- tracked.
  mt.__newindex = function(t, k, v)
    if (type(k) == 'number') and (k == math.floor(k)) then indxs = indxs + 1
    else keys = keys + 1 end

    all = all + 1
    t[k] = v
  end

  -- This allows us to have fields to access these datacounts, but won't count as
  -- actual keys or indexes.
  mt.__index = function(t, k)
    if k == 'keyCount' then return keys 
    elseif k == 'indexCount' then return indxs 
    elseif k == 'totalCount' then return all end
  end

  return setmetatable(x, mt)
end

これを使用する例は次のとおりです。

-- Note `36.35433` would NOT be counted as an integral index.
local foo = CountedTable { 1, 2, 3, 4, [36.35433] = 36.35433, [54] = 54 }
local bar = CountedTable { x = 23, y = 43, z = 334, [true] = true }
local foobar = CountedTable { 1, 2, 3, x = 'x', [true] = true, [64] = 64 }

print(foo.indexCount)    --> 5
print(bar.keyCount)      --> 4
print(foobar.totalCount) --> 6

実際の使用例

これが役に立てば幸い! :)

4
Miguel

Luaはテーブルを2つの別々の部分(ハッシュ部分と配列部分)として保存します。len演算子は配列部分のみを扱います。つまり、数値でインデックス付けされた値に加えて、下記のルールを使用するため、カウントする選択肢がありません。 pairs()関数を使用してテーブルを反復処理する必要がある「ハッシュ」値。

1
Faylixe