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

Can I only extract the same value from two tables?

就代码清洁度或效率而言,找到两个 Lua 编号 table 的“交集”的最佳方法是什么,即 table 仅包含tables?

中都存在的值

比如我有

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

因为3、4、5在ab中都有,所以我要{3,4,5}.

您需要 iterate table 和 output the value 之一,如果您在另一个 table 中找到它。对了,我的电脑下面的代码returns{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

我建议使用一种略有不同的方法,基于 sets。性能不一定会提高,代码会很干净,可理解和可扩展。

在Lua中,集合可以很容易地实现为table,其中键是集合项目,值是true,因此,检查项目是否存在在集合中,你只需要 if set[item] then.

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

请注意,两者都不包含 ab 上的嵌套循环:它是 O(a + b) 而不是 O( ab).

第一个:

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)), ', ') .. '}')

第三名:

local insert = table.insert -- 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 filter_array_through_set (array, set)
    local filtered = {}
    for _, value in ipairs (array) do
        if set [value] then
            insert (filtered, value)
        end
    end
    return filtered -- the order of array is preserved.
end

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