Удалить дубликаты из таблицы LUA по метке времени
Я был в стеке несколько дней назад для помощи вставки записей, чтобы предотвратить дублирование. Однако процесс их ввода идет медленно и они проскальзывают.
У меня есть база пользователей около 10000 игроков, и у них есть дубликаты записей. Я пытался отфильтровать эти дубликаты безуспешно. Примеры в стеке для меня не удавались.
Вот клип с моего стола
[18] =
{
["soldAmount"] = 25,
["buyer"] = [[@playername]],
["timestampz"] = 1398004426,
["secsSinceEvent"] = 55051,
["guildName"] = [[TradingGuild]],
["eventType"] = 15,
["seller"] = [[@myname]],
},
[19] =
{
["soldAmount"] = 25,
["buyer"] = [[@playername]],
["timestampz"] = 1398004426,
["secsSinceEvent"] = 55051,
["guildName"] = [[TradingGuild]],
["eventType"] = 15,
["seller"] = [[@myname]],
},
Метка времени совпадает, и они не должны были быть добавлены.
for k,v in pairs(sellHistory) do mSavedTHVars.Forever_Sales[k] = v
if mSavedTHVars.Forever_Sales.timestampz ~= sellHistory.timestampz then
table.insert(mSavedTHVars.Forever_Sales, sellHistory)
end end
Теперь мне нужно выяснить, как удалить текущие дубликаты, и вот что я попробовал.
function table_unique(tt)
local newtable = {}
for ii,xx in ipairs(tt) do
if table_count(newtable.timestampz, xx) ~= tt.timestampz then
newtable[#newtable+1] = xx
end
end
return newtable
end
Я надеюсь, что эта информация была чистой и понятной.
Спасибо!
ОБНОВИТЬ
Попытка № 20;)
for k,v in pairs(mSavedTHVars.Forever_Sales) do
if v == mSavedTHVars.Forever_Sales.timestampz then
table.remove(mSavedTHVars.Forever_Sales,k)
end
end
Пока не повезло
ОБНОВИТЬ
Это сработало
for k,v in pairs(mSavedTHVars.Forever_Sales) do mSavedTHVars.Forever_Sales[k] = v
if v.timestampz == mSavedTHVars.Forever_Sales.timestampz then
table.remove(mSavedTHVars.Forever_Sales, k)
end
end
Это хороший подход?
1 ответ
При условии, что mSavedTHVars.Forever_Sales[18]
а также mSavedTHVars.Forever_Sales[19]
те таблицы, которые вы перечислили в своем сообщении, тогда для удаления всех дубликатов, основанных на одной и той же отметке времени, проще всего создать "набор", основанный на отметке времени (поскольку отметка времени является вашим условием уникальности). Перебрать ваш mSavedTHVars.Forever_Sales
и для каждого элемента добавляйте элемент в новую таблицу, только если его отметка времени еще не установлена:
function removeDuplicates(tbl)
local timestamps = {}
local newTable = {}
for index, record in ipairs(tbl) do
if timestamps[record.timestampz] == nil then
timestamps[record.timestampz] = 1
table.insert(newTable, record)
end
end
return newTable
end
mSavedTHVars.Forever_Sales = removeDuplicates(mSavedTHVars.Forever_Sales)
Обновление на основе вопросов обновления:
Мой комментарий к следующему предложенному решению:
for k,v in pairs(mSavedTHVars.Forever_Sales) do
mSavedTHVars.Forever_Sales[k] = v
if v.timestampz == mSavedTHVars.Forever_Sales.timestampz then
table.remove(mSavedTHVars.Forever_Sales, k)
end
end
Проблема в том, что я не понимаю, как это может работать. Когда вы делаете for k,v in pairs(mSavedTHVars.Forever_Sales) do
затем v
является mSavedTHVars.Forever_Sales[k]
поэтому следующая строка mSavedTHVars.Forever_Sales[k] = v
ничего не делает. затем if v.timestampz == mSavedTHVars.Forever_Sales.timestampz
сравнивает временную метку v
то есть mSavedTHVars.Forever_Sales[k]
со значением timestampz
поле в mSavedTHVars.Forever_Sales
, Но последний - это таблица без такого поля, поэтому правая часть ==
будет ноль, поэтому условие будет истинным, только если v.timestampz
это ноль, что я не думаю, что это когда-либо так.
Основная причина, по которой я использовал решение создания новой таблицы вместо удаления дубликатов из существующей таблицы, заключается в том, что вы можете редактировать таблицу, перебирая ее по парам или парам. Если бы вы использовали обратный счетчик, вероятно, все было бы в порядке (но я не проверял, проверьте, чтобы убедиться):
function removeDuplicates(tbl)
local timestamps = {}
local numItems = #tbl
for index=numItems, 1, -1, do
local record = tbl[index]
if timestamps[record.timestampz] ~= nil then
table.remove(newTable, index)
end
timestamps[record.timestampz] = 1
end
end
Также я думаю, что цель функции не так ясна, но, возможно, это всего лишь личные предпочтения.