确定表/变量的更改

时间:2012-01-30 22:01:56

标签: lua

我有几个表/变量(下面采样):

mytable = { ['100'] = { ['2']=0,['3']=0,['5']=0,['6']=0,['7']=0,['9']=0},
            ['101'] = { ['8']={['81']=0,['86']=0},
                        ['13']={['81']=0},
                        ['30']={['81']=0,['82']=0,['83']=0,['84']=0,['85']=0} },
            ['102'] = { ['81']={['location']='left',['3']=1} }
          }
mytable2 = 5

我需要一个函数来传递一个表/变量结构,就像上面两个中的一个(可以是其中一个),它将区分当前和以前的数据,并返回一个表/变量,它只包含已更改的数据自上次调用每个客户端(与表/变量一起传递的唯一ID)。表可以在函数执行之间增长或改变。<​​/ p>

因此,如果在执行函数之间发生以下更新:

mytable['101']['8']['81']=1
mytable['102']['81']['4']=0

该函数将返回

mytable = { ['101'] = { ['8']={['81']=1} },
            ['102'] = { ['81']={['4']=0} }
          } 

2 个答案:

答案 0 :(得分:1)

您将遇到一些关于表的事情:表是通过引用传递的(除非您执行深层复制)。所以如果你这样做:

A={1,2,3}
B=A
B[1]=nil
--[[then]]
print(A[1]==nil)-- prints true.

因此,拥有“新桌子”和“旧桌子”需要您付出额外的努力。 要么你在表格的deep copy做一些事情作为参考(不是有效率)。

或者您不直接更改表本身,而是使用代理。这仅适用于单个级别的表,但我认为您可以将结构嵌入代理表中,并将值包含在实际值中:

mytable={}
do
    local changes={}
    mt={
    __index=function(t,k)
        if k=="reset" then
             return function()
                 changes={}
                 return true
             end
        elseif k=="getChanges" then
             return function() return changes end
        else
             return mytable[k]
        end
    end,
    __newindex=function(t,k,v)
        changes[k]=v
        mytable[k]=v
    end
    }
    prox=setmetatable({},mt)
end
prox[1]=1
prox[2]=2
for k,v in pairs(prox:getChanges()) do print(k,v) end
prox:reset()
for k,v in pairs(prox:getChanges()) do print(k,v) end

递归地实现这可能是一些工作。我想你应该问自己一个问题,如果编写一个简单的函数将事务日志保存到你的表中是不是更简单。

答案 1 :(得分:0)

虽然这会添加空键,但我认为它对我有用:

--t is the table and pt is the previous table

function deepchange(t,pt)
if (pt == nil) then return t, true end
if type(t) ~= 'table' then return t,t ~= pt end
local res = {}
local sd = false
for k,v in pairs(t) do
    if type(v) == 'table' then v = deepchange(v,pt[k]) end
    if pt[k] ~= v then 
        res[k] = v
        sd = true
    end
end
return res,sd
end

更新以处理第二种情况并删除与get和set metatable相关的不必要的行...

再次更新以处理以前的空表。