两个表之间的差异为一个表

时间:2019-08-07 06:17:58

标签: lua set-difference

穿着短裤

  

t1 = {1,3,5,7,9}

     

t2 = {1,2,3,4,5,6,7,8,9}

     

想要的结果:t3 = {2,4,6,8}

长期解释

我有一个场景中的对象的列表,并且我有一个不在场景中的所有对象的列表。我正在尝试编写一些简单的代码,使我可以向场景中添加对象,但要确保它不会加载已经加载的对象。

所以我可以说类似...

  

SafeAdd(2,currentOBJlist,notLoadedOBJList)

并从“ notLoadedOBJList”中的2个随机对象中加载应用,但所选对象不在“ currentOBJlist”中

1 个答案:

答案 0 :(得分:2)

未排序的数组

Lua中的表除了是数组/列表之外,它也是地图/字典/ set

通过为列表中的每个元素分配true来进行设置;这样,您可以通过查找键将其作为一组使用。如果返回的键是nil,则该键不存在,否则将返回true

function notInScene(allObjects, objectsInScene)
  -- build a set out of objectsInScene
  -- this step can be avoided, if it's already a set
  local set = {}
  for _, v in ipairs(objectsInScene) do
    set[v] = true
  end

  -- populate output
  local notPresent = { }
  for _, v in ipairs(allObjects) do
    if (set[v] == nil) then
      table.insert(notPresent, v)
    end
  end
  return notPresent
end

local t1 = {1,3,5,7,9}
local t2 = {1,2,3,4,5,6,7,8,9}
local t3 = notPresent(t2, t1)
for _, v in ipairs(t3) do print(v) end

输出

2
4
6
8

请注意,我们正在将objectsInScene复制为一组;应避免这种情况,如果可能的话,即在最初构建objectsInScene时将其设为集合。

排序数组

如果保证两个列表都可以排序,那么我们比建立一个集合然后查找它要好得多-两遍解决方案,效率不高。

function notInScene(allObjects, objectsInScene)
  j = 1
  local notPresent = {}
  for i = 1, #allObjects do
    if (allObjects[i] == objectsInScene[j]) then
      j = j + 1
    elseif (allObjects[i] < objectsInScene[j]) then
      table.insert(notPresent, allObjects[i])
    end
    i = i + 1
  end
  return notPresent
end

这给出了相同的结果,但是没有花费额外的空间或时间;比以前的方法更好。