通过时间戳从LUA表中删除重复项

时间:2014-04-23 03:50:28

标签: lua lua-table deduplication

几天前我在堆栈上寻求帮助插入记录以防止重复。然而,进入这些过程的过程很慢,而且它们会滑入。

我有大约10,000名玩家的用户群,并且他们有重复的条目..我一直试图过滤掉这些重复项而没有成功。堆栈上的示例对我来说没有任何淘汰。

这是我表中的剪辑

    [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 个答案:

答案 0 :(得分:2)

假设mSavedTHVars.Forever_Sales[18]mSavedTHVars.Forever_Sales[19]是您在帖子中列出的表格,那么要根据相同的时间戳删除所有重复项,最简单的方法是创建" set"基于时间戳(因为时间戳是唯一性的条件)。循环遍历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时,vmSavedTHVars.Forever_Sales[k],因此下一行mSavedTHVars.Forever_Sales[k] = v不执行任何操作。然后if v.timestampz == mSavedTHVars.Forever_Sales.timestampzv的时间戳(即mSavedTHVars.Forever_Sales[k])的时间戳与timestampz中的mSavedTHVars.Forever_Sales字段的值进行比较。但后者是一个没有这样字段的表,所以==的右侧将是零,所以只有v.timestampz为零时才会出现这种情况,我不认为是从来没有这样。

我使用创建新表而不是从现有表中删除重复项的解决方案的主要原因是您可以在使用pair或ipairs迭代它时编辑表。如果您使用反向计数器,它可能会好的(但我没有测试,测试以确定):

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

此外,我认为该功能的意图并不明确,但也许这只是个人偏好。