Определить изменения в таблице / переменной - PullRequest
0 голосов
/ 31 января 2012

У меня есть несколько таблиц / переменных (пример ниже):

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

Мне нужна функция для передачи таблицы / переменной, структурированной как одна из двух выше (может быть любая), которая будет различатьтекущие и предыдущие данные и возвращают таблицу / переменную, которая состоит только из данных, которые изменились с момента последнего вызова для каждого клиента (уникальный идентификатор, переданный вместе с таблицей / переменной).Таблицы могут увеличиваться или изменяться в зависимости от выполнения функции.

Так что если между выполнением функции произошли следующие обновления:

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

, функция вернет

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

Ответы [ 2 ]

1 голос
/ 31 января 2012

В таблицах, с которыми вы столкнетесь, есть одна вещь: таблицы передаются по ссылке (если вы не делаете глубокую копию). Так что если вы делаете:

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

Таким образом, наличие «новой таблицы» и «старой таблицы» требует от вас дополнительных усилий. Либо вы делаете глубокую копию таблицы, чтобы иметь что-то в качестве ссылки (не эффективно).

Или вы сами не меняете таблицу, а используете прокси. Это делается только для одного уровня таблиц, но я думаю, что вы могли бы встроить структуру в таблицу прокси и иметь значения в реальных:

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

Реализация этого рекурсивно может быть частью работы. Я полагаю, вам следует задать себе вопрос, не проще ли написать простую функцию, которая хранит журналы транзакций в вашей таблице.

0 голосов
/ 01 февраля 2012

Хотя это добавляет пустые ключи, я думаю, что это будет работать для меня:

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

ОБНОВЛЕНО для обработки второго случая и удаления ненужных строк, связанных с получением и установкой метатабельного ...

Снова ОБНОВЛЕНО для обработки нулевых предыдущих таблиц.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...