2012-04-29 16 views
3

存在しない連想配列キーのデフォルト値を自動的に処理する、Pythonで利用可能なcollections.defaultdictに似た機能がLuaにありますか?Pythonのdefaultdict機能はLuaで利用可能です

エラーの代わりにnilvに設定するコードを以下に示します。そこで、基本的a[2]への道(存在しないキー)はデフォルトでtableこと:

a = {} 
v = a[2][3] 

>>> PANIC: unprotected error in call to Lua API (main.lua:603: attempt to index field '?' (a nil value)) 

Pythonで、それは次のように行うことができます。

>>> import collections 
>>> a = collections.defaultdict(dict) 
>>> print a[2] 
{} 

答えて

5

はそれを行うにはLuaの標準関数があります?いいえ。しかし、メタテーブルを使って簡単に行うことはできます。あなたも、このようなテーブルを作成するための関数を書くことができます。各要素は同じデフォルト値を取得します

function CreateTableWithDefaultElement(default) 
    local tbl = {} 
    local mtbl = {} 
    mtbl.__index = function(tbl, key) 
    local val = rawget(tbl, key) 
    return val or default 
    end 
    setmetatable(tbl, mtbl) 
    return tbl 
end 

注意を。したがって、デフォルト値をテーブルにすると、返されるテーブルの各「空の」要素は、同じテーブルを効果的に参照します。それがあなたが望むものでないなら、あなたはその機能を変更しなければならないでしょう。

+0

パーフェクト!ありがとう:) –

1

このコードを見つけた人がテーブル、オブジェクトなどと互換性のあるバージョンを必要とするならば、私はこのコードを自分のバージョンと共有すると考えていました。また、Nicolのソリューションとは対照的に、これは実際にテーブルに要求されたエントリを作成します。

function defaultdict(default_value_factory) 
    local t = {} 
    local metatable = {} 
    metatable.__index = function(t, key) 
     if not rawget(t, key) then 
      rawset(t, key, default_value_factory(key)) 
     end 
     return rawget(t, key) 
    end 
    return setmetatable(t, metatable) 
end 

使用例:

d = defaultidct(function() return {} end) 
table.insert(d["people"], {"Bob", "The Builder"}) 

names = defaultdict(function(key) return key end) 
print(names["bob"]) -- bob 
names["bob"] = "bob the builder" 
names["ashley"] = "ashley the fire princess" 
関連する問題