我只能从两个表中提取相同的值吗?

时间:2020-10-10 04:46:54

标签: arrays lua compare intersection

从代码清洁性或效率方面,找到两个Lua编号表(即仅包含两个表中都存在的值的表)的“交集”的最佳方法是什么?

例如,我有

a={1,2,3,4,5}
b={3,4,5,6,7}

由于在ab中都找到了3、4和5,所以我要{3,4,5}

2 个答案:

答案 0 :(得分:0)

您需要在其中一个表上iterate,如果在另一个表中找到,则output the value。在我的计算机上,以下代码返回{3,4,5},它基本上实现了intersection of 2 sets

a={1,2,3,4,5}
b={3,4,5,6,7}

function Contains (Array, Item)

  local Found = false
  local Index = 1

  while ((not Found) and (Index <= #Array)) do
    if Array[Index] == Item then
      Found = true
    else
      Index = Index + 1
    end
  end

  return Found  
end

function Intersects (Ta, Tb)

  local Result = { }
  local Index

  for Index = 1, #Tb do
    if Contains(Ta, Tb[Index]) then
      Result[#Result + 1] = Tb[Index]
    end
  end

  return Result
end

Result = Intersects(a, b)

-- Print the results
local Index, Value

for Index, Value in ipairs(Result) do
  print(Value)
end

答案 1 :(得分:0)

我建议基于 sets 的方法稍有不同。性能并不一定会提高,代码会干净,可理解且可扩展。

在Lua中,一个集合可以很容易地实现为一个表,其中键是集合项,值是true,因此,要检查集合中是否存在某个项,您只需要{{1 }}。

我将给出代码的三个变体。首先干净地实现了一个相交运算符,但随后必须将结果集转换回索引的Lua表。第二个立即返回两个集合的交集作为数组。第三是前两者之间的折衷。

请注意,它们都不包含在if set[item] thena上的嵌套循环:它是 O(a + b)而不是 O(ab)

第一:

b

第二:

local insert, sort = table.insert, table.sort -- localise for performance.

local a = {1,2,3,4,5}
local b = {3,4,5,6,7}

local function toset (tbl)
    local set = {}
    for _, value in ipairs (tbl) do
        set [value] = true
    end
    return set
end

local function intersect (set1, set2)
    local intersection = {}
    for item, _ in pairs (set1) do
        if set2 [item] then
            intersection [item] = true
        end
    end
    return intersection
end

local function toarray (set)
    local array = {}
    for item, _ in pairs (set) do
        insert (array, item)
    end
    sort (array)    -- since you want {3,4,5} not {4,5,3}
    return array
end

-- Fortunately, table.concat does not require previous tostring:
print ('{' .. table.concat (toarray (intersect (toset (a), toset (b))), ', ') .. '}')

第三:

local insert, sort = table.insert, table.sort -- localise for performance.

local a = {1,2,3,4,5}
local b = {3,4,5,6,7}

local function toset (tbl)
    local set = {}
    for _, value in ipairs (tbl) do
        set [value] = true
    end
    return set
end

local function intersect_and_to_array (set1, set2)
    local array = {}
    for item, _ in pairs (set1) do
        if set2 [item] then
            insert (array, item)
        end
    end
    sort (array)    -- since you want {3,4,5} not {4,5,3}
    return array
end

-- Fortunately, table.concat does not require previous tostring:
print ('{' .. table.concat (intersect_and_to_array (toset (a), toset (b)), ', ') .. '}')