2009-08-09 2 views
96

テーブルが空である(つまり、現在、配列スタイル値もdictスタイル値も含まない)かどうかを判断する最も効率的な方法は何ですか?Luaテーブルが空である(エントリを含まない)かどうかを判断する最も効率的な方法は?

現在、私はnext()を使用しています:

if not next(myTable) then 
    -- Table is empty 
end 

は、より効率的な方法はありますか?

注:それだけでテーブルの配列形式の値に作用するよう#オペレータが、ここでは十分ではない - リターン0の両方が、また、テーブル変数がnilであるかどうかをチェックすることはないことに注意してくださいので、これ#{test=2}#{}と区別がつきません私がゼロの値を探しているのではなく、0のエントリ(すなわち、{})のテーブルを探しているので十分ではありません。

答えて

118

あなたのコードは効率的ですが間違っています。 ({[false]=0}を考えてみましょう。)正しいコードは、効率を最大にするため

if next(myTable) == nil then 
    -- myTable is empty 
end 

であるあなたはローカル変数にnextをバインドすることをお勧めします、例えば、

... 
local next = next 
... 
... if next(...) ... 
+1

技術的な正しさについての良い点。私が元のコードを利用していた特定のケースでは、 'false'は期待されたキーではないので、もし' not 'がうまくいけば、将来は 'nil'と比較する傾向があります、ちょうどよい習慣として。そして、はい、私は速度のためにローカルのvarsに一般的なユーティリティ関数をバインドしてきました。しかし、入力をありがとう。 – Amber

+1

コードが意図したとおりに動作するときに、間違っていることに同意するのは難しいと思う。 –

+3

なぜ 'local next'を実行してスピードを上げるのか? – Moberg

1

メタ可能な「newindex」キーを使用することで、要素の数を数えることも可能です。 nilではないものを割り当てるときは、カウンタをインクリメントします(カウンタはメタテーブルにも存在する可能性があります)。nilを割り当てるときは、カウンタを減らします。空のテーブルのための

テストは0

でカウンタをテストすることですここで私もあなたのソリューションのように行う、と私は正直に私の解決策が速く、全体であると仮定することはできませんmetatable documentation

へのポインタです。

+5

を返す元の質問は、単に「アレイ」のエントリーを数えるに関するものではありません。 – lhf

+3

0x6の提案は、配列スタイルのエントリに特有ではありません(newindexは、数値インデックスと非数値インデックスの両方で機能します)。しかし、キーがすでにテーブルに存在する場合、__newindexはトリガしないので、主な問題は 'nil'が割り当てられたときを検出することです。 – Amber

+3

このトリックを動作させるには、メタデータは '__index'と' __newindex'の両方を実装し、実際のデータをシャドウテーブルに格納し、実テーブルを空にして '__index'を呼び出すようにしなければなりません。大声で考えてみると、私はすべてのシングルルックアップのコストがそれに値するものではないと考えています。 – RBerteig

0

これは、あなたが何を望むか、おそらくです:

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 
+8

'next()'は 'pairs()'をループするより効率的(かつ簡潔)です。 – Amber

+7

実際、 'pairs()' *をループするのは基本的に 'next()'手法を使用するだけですが、オーバーヘッドが増えます。 – dubiousjim

+7

また、標準の 'table'ライブラリへの書き込みはお勧めしません。 –

-1

私はこれが古かったと知っていますが、何とかあなたを誤解するかもしれませんが、テーブルが空であることを望みます。つまり、それが本当に必要かどうかをチェックしていない限り私が間違っていない限り、あなたは単にそれを作り直すことによってそれをクリアすることができます。これは以下の構文で行うことができます。

yourtablename = {} -- this seems to work for me when I need to clear a table. 
+4

それは問題ではありません。 –

-4

#を試してください。これは、テーブルにあるすべてのインスタンスを返します。テーブル内のインスタンスがない場合、それは0

if #myTable==0 then 
print('There is no instance in this table') 
end 
+1

質問者は、「#」はここでは十分ではないと言い、理由を説明します。なぜこれらの理由でこのことが起こるのか説明できますか? – MathSquared

+0

まあ...私は知らない。私はこれで新しいので、私が知っている唯一の方法は# – arthurgps2

関連する問題