web-dev-qa-db-ja.com

Luaテーブルのエントリ数を取得する方法は?

「Googleで検索してください」という質問のように聞こえますが、どういうわけか答えが見つかりません。 Lua #演算子は整数キーを持つエントリのみをカウントするため、table.getnもカウントします。

tbl = {}
tbl["test"] = 47
tbl[1] = 48
print(#tbl, table.getn(tbl))   -- prints "1     1"

count = 0
for _ in pairs(tbl) do count = count + 1 end
print(count)            -- prints "2"

allエントリの数をカウントせずに取得するにはどうすればよいですか?

118
Roman Starkov

あなたはすでに問題の解決策を持っています-唯一の方法はpairs(..)でテーブル全体を反復することです。

function tablelength(T)
  local count = 0
  for _ in pairs(T) do count = count + 1 end
  return count
end

また、「#」演算子の定義はそれよりも少し複雑であることに注意してください。この表を取り上げて説明しましょう。

t = {1,2,3}
t[5] = 1
t[9] = 1

マニュアルによると、any of 3、5、および9は#tの有効な結果です。それを使用する唯一の正しい方法は、nil値のない1つの連続した部分の配列を使用することです。

114
u0b34a0f6ae

エントリの数を追跡するためにメタテーブルを設定できます。この情報が頻繁に必要な場合、これは反復よりも高速です。

19
ergosys

penlight library を使用できます。これには関数 size があり、テーブルの実際のサイズを示します。

Luaでプログラミングや欠落しているときに必要になる可能性のある関数の多くを実装しています。

これを使用するためのサンプルを次に示します。

> tablex = require "pl.tablex"
> a = {}
> a[2] = 2
> a[3] = 3 
> a['blah'] = 24

> #a
0

> tablex.size(a)
3
2
user11464249

方法は1つありますが、期待はずれの可能性があります。追加の変数(またはテーブルのフィールドの1つ)を使用してカウントを保存し、挿入するたびにカウントを増やします。

count = 0
tbl = {}

tbl["test"] = 47
count = count + 1

tbl[1] = 48
count = count + 1

print(count)   -- prints "2"

他に方法はありません。#演算子は、連続したキーを持つ配列のようなテーブルでのみ機能します。

1
kikito

テーブル内のエントリ数を取得する最も簡単な方法は、「#」を使用することです。 #tableNameは、番号が付けられている限り、エントリの数を取得します。

tbl={
    [1]
    [2]
    [3]
    [4]
    [5]
}
print(#tbl)--prints the highest number in the table: 5

残念ながら、番号が付けられていないと機能しません。

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

    local new_t = {}
    local mt = {}

    -- `all` will represent the number of both
    local all = 0
    for k, v in pairs(x) do
        all = all + 1
    end

    mt.__newindex = function(t, k, v)
        if v == nil then
            if rawget(x, k) ~= nil then
                all = all - 1
            end
        else
            if rawget(x, k) == nil then
                all = all + 1
            end
        end

        rawset(x, k, v)
    end

    mt.__index = function(t, k)
        if k == 'totalCount' then return all
        else return rawget(x, k) end
    end

    return setmetatable(new_t, mt)
end

local bar = CountedTable { x = 23, y = 43, z = 334, [true] = true }

assert(bar.totalCount == 4)
assert(bar.x == 23)
bar.x = nil
assert(bar.totalCount == 3)
bar.x = nil
assert(bar.totalCount == 3)
bar.x = 24
bar.x = 25
assert(bar.x == 25)
assert(bar.totalCount == 4)
1
Sleepwom

テーブルの要素がinsertメソッドによって追加された場合、getnは正しく戻ります。それ以外の場合は、すべての要素をカウントする必要があります

mytable = {}
element1 = {version = 1.1}
element2 = {version = 1.2}
table.insert(mytable, element1)
table.insert(mytable, element2)
print(table.getn(mytable))

2を正しく印刷します

0
Yongxin Zhang