Удалить дубликаты из таблицы 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

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

Другие вопросы по тегам