我在lua中有两个表(在生产中,a有18个元素,b有8个):
local a = {1,2,3,4,5,6}
local b = {3,5,7,8,9}
我需要返回' a'省略' b'中的任何共同元素 - {1,2,4,6}类似于ruby命令a-b(如果a和b是数组)。
我能想到的最好的lua逻辑是:
local function find(a, tbl)
for _,a_ in ipairs(tbl) do if a_==a then return true end end
end
function difference(a, b)
local ret = {}
for _,a_ in ipairs(a) do
if not find(a_,b) then table.insert(ret, a_) end
end
return ret
end
local a = {1,2,3,4,5,6}
local b = {3,5,7,8,9}
local temp = {}
temp = difference(a,b)
print(temp[1],temp[2],temp[3],temp[4])
我需要非常快速地遍历这些表格比较(在生产中每秒最少10K次)。有更清洁的方法吗?
==
这是redis服务器端脚本的一部分,我必须保护我的Redis CPU。在干净的Lua流程之外,我还有两个选择:
1.创建两个redis临时密钥,然后为42(
的大(O)运行烧结2.将a和b返回ruby进行数组比较并发回结果。
答案 0 :(得分:7)
试试这个:
function difference(a, b)
local aa = {}
for k,v in pairs(a) do aa[v]=true end
for k,v in pairs(b) do aa[v]=nil end
local ret = {}
local n = 0
for k,v in pairs(a) do
if aa[v] then n=n+1 ret[n]=v end
end
return ret
end
答案 1 :(得分:1)
你可以这样做(未经测试):
function difference(a, b)
local ai = {}
local r = {}
for k,v in pairs(a) do r[k] = v; ai[v]=true end
for k,v in pairs(b) do
if ai[v]~=nil then r[k] = nil end
end
return r
end
如果你可以修改a
,那就更短了:
function remove(a, b)
local ai = {}
for k,v in pairs(a) do ai[v]=true end
for k,v in pairs(b) do
if ai[v]~=nil then a[k] = nil end
return r
end
如果您的表已经排序,您还可以将两个表并行扫描,类似于以下伪代码:
function diff(a, b)
Item = front of a
Diff = front of b
While Item and Diff
If Item < Diff then
Item is next of a
Else if Item == Diff then
remove Item from a
Item = next of a
Diff = next of b
Else # else Item > Diff
Diff = next of b
这不使用任何额外的表。即使您想要新表而不是就地差异,也只需要一个新表。我想知道它如何与哈希表方法(remove
)进行比较。
请注意,循环次数无关紧要,如果a
和b
较小,则这些与您的算法之间不会有重大差异。您需要在a
和b
中至少包含100个项目,甚至可能需要1000个。
答案 2 :(得分:0)
也许是这样的:
function get_diff (t1, t2)
local diff = {}
local bool = false
for i, v in pairs (t1) do
if t2 and type (v) == "table" then
local deep_diff = get_diff (t1[i], t2[i])
if deep_diff then
diff[i] = deep_diff
bool = true
end
elseif t2 then
if not (t1[i] == t2[i]) then
diff[i] = t1[i] .. ' -- not [' .. t2[i] .. ']'
bool = true
end
else
diff[i] = t1[i]
bool = true
end
end
if bool then
return diff
end
end
local t1 = {1, 2, 3, {1, 2, 3}}
local t2 = {1, 2, 3, {1, 2, 4}}
local diff = get_diff (t1, t2)
结果:
diff = {
nil,
nil,
nil,
{
[3] = "3 -- not [4]"
}
}