Lua中两个表的区别

我在 Lua 中有两个表(在生产中,a 包含 18 个元素,b 包含 8 个元素):

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

我需要返回省略了 'b' 中任何公共元素的 'a' -- {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 临时键,然后运行 sinter,大O为 42

  • 18 sadd(a)
  • 8 sadd(b)
  • 16 sinter(a,b)

2.将 a 和 b 都返回到 Ruby 中进行数组比较,然后发送结果回来。

  • 每秒几千个连接的来回网络成本会耗费资源。
点赞
用户107090
用户107090

尝试一下:

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
2014-07-08 00:55:31
用户869951
用户869951

你可以这样做(未测试):

`` ` 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     返回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     返回r end

`` `

如果您的表已排序,则还可以一起对两个表进行并行扫描,例如以下伪代码:

`` ` function diff(a,b)     项目= a的正面     Diff = b的正面     While Item and Diff        如果Item <Diff,则            Item是a的下一个        Else if Item == Diff then            从a中删除项目            Item = a的下一个            Diff = b的下一个        Else         #否则Item> Diff            Diff = b的下一个

`` `

这不使用任何额外的表。即使您想要新表而不是原地差分,也只需要一个新表。我想知道它与哈希表方法(remove)相比如何。

请注意,无论循环多少次,如果ab很小,则这些算法之间没有主要区别。您需要至少100个项目在ab中,甚至可能需要1000个。

2014-07-08 04:20:34
用户12968803
用户12968803
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]"
  }
}
2020-12-05 17:48:38