2012-04-29 73 views
3

Lua中是否有類似於Python中可用的collections.defaultdict的功能,它可以自動處理不存在的關聯數組鍵的默認值?Lua中是否有Python的defaultdict功能

我希望下面的代碼將nil設置爲v而不是錯誤。所以基本上辦法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標準函數來做到這一點?不,但你可以用metatables輕鬆完成。你甚至可以編寫一個函數來創建這樣的表:

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

完美!謝謝 :) – 2012-04-29 10:59:39

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"