我只能从两个表中提取相同的值吗?
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在a
和b
中都有,所以我要{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 将两个集合的交集作为一个数组。第三个是前两者的折衷。
请注意,两者都不包含 a
和 b
上的嵌套循环:它是 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)), ', ') .. '}')
就代码清洁度或效率而言,找到两个 Lua 编号 table 的“交集”的最佳方法是什么,即 table 仅包含tables?
中都存在的值比如我有
a={1,2,3,4,5}
b={3,4,5,6,7}
因为3、4、5在a
和b
中都有,所以我要{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 将两个集合的交集作为一个数组。第三个是前两者的折衷。
请注意,两者都不包含 a
和 b
上的嵌套循环:它是 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)), ', ') .. '}')