回答:
あなたのコードは効率的ですが間違っています。(検討してください{[false]=0}
。)正しいコードは
if next(myTable) == nil then
-- myTable is empty
end
最大の効率を得るにはnext
、ローカル変数にバインドする必要があります。たとえば、
...
local next = next
...
... if next(...) ...
local next
ですか?
local next
、現在のブロックにがある場合はそれを使用し、次に次のブロックに登って繰り返します。ローカルから外れると、グローバルネームスペースが使用されます。これは馬鹿げたバージョンですが、結局のところ、それは間違いなくプログラム速度の違いを意味します。
1つの可能性は、メタテーブルの「newindex」キーを使用して、要素の数を数えることです。ないものを割り当てるnil
場合は、カウンターをインクリメントします(カウンターはメタテーブルにも存在する可能性があります)。また、割り当てる場合nil
は、カウンターをデクリメントします。
空のテーブルのテストは、カウンターを0でテストすることです。
これがメタテーブルのドキュメントへのポインタです
私はあなたのソリューションが好きですが、正直なところ、私のソリューションが全体的に高速であるとは思いません。
nil
キーがすでにテーブルに存在する場合、__ newindexはトリガーされないため、主な問題はいつが割り当てられるかを検出することです。
__index
と__newindex
影のテーブルに実際のデータを格納し、実際のテーブルにはそのように空に保ち、__index
すべてで呼び出されます。大声で考えると、1回の検索で発生するコストはそれだけの価値があるとは思えません。
これはおそらくあなたが欲しかったものです:
function table.empty (self)
for _, _ in pairs(self) do
return false
end
return true
end
a = { }
print(table.empty(a))
a["hi"] = 2
print(table.empty(a))
a["hi"] = nil
print(table.empty(a))
出力:
true
false
true
next()
ループするよりも効率的(かつ簡潔)ですpairs()
。
pairs()
は基本的にこのnext()
手法を使用するだけですが、オーバーヘッドが大きくなります。
table
ライブラリへの書き込みはお勧めしません。
オーバーロードされた場合に__eqの評価を回避することをお勧めします。
if rawequal(next(myTable), nil) then
-- myTable is empty
end
または
if type(next(myTable)) == "nil" then
-- myTable is empty
end
を使用してみてください#
。テーブルにあるすべてのインスタンスを返します。テーブルにインスタンスがない場合は、次を返します0
if #myTable==0 then
print('There is no instance in this table')
end
#
ここでは十分ではなく、理由を説明します。これがこれらの理由を回避する理由を説明できますか?
false
、期待されるキーではないのでif not
問題nil
なく機能しますが、将来的には、良い習慣として、代わりに比較する習慣をつけるでしょう。そして、はい、速度を上げるために、一般的なユーティリティ関数をローカル変数にバインドしています。入力ありがとうございます。