在Lua中,表的串联指的是将两个或多个表合并为一个表的过程。可以使用运算符“..”来将表合并起来,也可以使用函数table.concat()。注意,这两个方式只适用于两个或多个数字或字符串类型的表。如果要串联非数字或非字符串类型的表,需要自行编写代码。

鉴于 Lua 中没有内置函数,我正在寻找一种允许我将表追加在一起的函数。我已经谷歌过很多,并尝试了我遇到的每个解决方案,但似乎没有一个可以正常工作。

场景如下:我正在使用嵌入在应用程序中的 Lua。应用程序的内部命令以表的形式返回一系列值。

我尝试的是,在循环中递归调用该命令,并将以前迭代中返回的值(同样以表的形式)附加到表中。


编辑

对于将来遇到此帖子的人,请注意 @gimf 发布的内容。由于 Lua 中的表与数组一样(即使在列表上下文中),没有真正正确的将一个表附加到另一个表的方法。最接近的概念是合并表。请参见帖子 “Lua-合并表吗?”以获取有关此事的帮助。

原文链接 https://stackoverflow.com/questions/1410862

点赞
stackoverflow用户15529
stackoverflow用户15529

如果你想合并两个表格,但需要一个结果表格的深层副本,无论出于什么原因,请使用另一个有关合并表格的SO问题以及从lua-users复制一些深度复制代码。

(编辑)

嗯,也许你可以编辑你的问题提供一个最小的例子... 如果你的意思是一个表格

 { a = 1, b = 2 }

与另一个表格连接

{ a = 5, b = 10 }

应该得出

{ a = 1, b = 2, a = 5, b = 10 }

那么你没有希望了。键是唯一的。

看来你想要一个键值对列表,像{ { a, 1 }, { b, 2 }, { a, 5 }, { b, 10 } }。根据你的应用,你也可以使用最终结构,比如{ a = { 1, 5 }, b = { 2, 10 } }

但是,在Lua表格中,简单地“连接”表格的概念是没有意义的。

2009-09-11 14:02:52
stackoverflow用户68204
stackoverflow用户68204

通常在 Lua 中,连接任意表的概念是没有意义的,因为一个键只能有一个值。

但是也有特殊情况下连接是有意义的。一种情况是包含简单数组的表,这可能是旨在返回结果列表的函数的自然结果。

在这种情况下,你可以编写:

-- 返回包含其所有参数连接的新数组。标量参数以原地包含,数组参数的值被浅复制到最终数组中。
-- 注意,userdata 和函数值被视为标量。
function array_concat(...)
    local t = {}
    for n = 1,select("#",...) do
        local arg = select(n,...)
        if type(arg)=="table" then
            for _,v in ipairs(arg) do
                t[#t+1] = v
            end
        else
            t[#t+1] = arg
        end
    end
    return t
end

这是一个浅复制,不会尝试找出 userdata 或函数值是否是某种需要不同处理的容器或对象。

另一种实现方式可能修改第一个参数而不是创建一个新表。这将节省复制的成本,并使 array_concat 与字符串上的 .. 运算符不同。

编辑:Joseph Kingry的评论所述,我未能正确从 ... 中提取每个参数的实际值。我还没有返回合并后的表。这就是我在答案框中编程而没有测试代码的结果。

2009-09-12 01:07:27
stackoverflow用户542353
stackoverflow用户542353

这是一个我所做的实现,与 RBerteig 上面的实现类似,但使用了隐藏参数 arg。当函数收到可变数量的参数时,该参数是可用的。个人认为这比 select 语法更易读。

function array_concat(...)
    local t = {}

    for i = 1, arg.n do
        local array = arg[i]
        if (type(array) == "table") then
            for j = 1, #array do
                t[#t+1] = array[j]
            end
        else
            t[#t+1] = array
        end
    end

    return t
end
2011-11-28 18:57:23
stackoverflow用户1321625
stackoverflow用户1321625

将两个表格相加,可以执行以下操作:

    ii=0
for i=#firsttable, #secondtable+#firsttable do
    ii=ii+1
    firsttable[i]=secondtable[ii]
end

使用第一个表格作为要添加的变量,代码会将第二个表格加到第一个表格末尾。

  • i 是表格或列表的起始编号。
  • #secondtable+#firsttable 是结束处。

它从要添加的第一个表格的末尾开始,并在 for 循环中从第二个表格的末尾结束,因此可以处理任何大小的表格或列表。

2012-04-09 10:05:39
stackoverflow用户1301806
stackoverflow用户1301806

过于复杂了,不是吗?

以下是我的实现:

function TableConcat(t1,t2)
    for i=1,#t2 do
        t1[#t1+1] = t2[i]
    end
    return t1
end
2013-03-07 18:00:10
stackoverflow用户3979429
stackoverflow用户3979429

一种简单的方法来实现你想要的:

local t1 = {1, 2, 3, 4, 5}
local t2 = {6, 7, 8, 9, 10}

local t3 = {unpack(t1)}
for I = 1,#t2 do
    t3[#t1+I] = t2[I]
end
2015-02-23 03:27:56
stackoverflow用户226086
stackoverflow用户226086

还有一种方法:

for _,v in ipairs(t2) do
    table.insert(t1, v)
end

对于我来说,这是最易读的方法 - 它迭代了第二个表并将其值附加到第一个表中,没有多余的步骤。好奇与上面的显式索引[]在速度上相比如何。

2015-03-20 23:36:56
stackoverflow用户1819824
stackoverflow用户1819824

这是我实现的连接一组只包含整数索引表的代码,供您参考。

  1. 定义连接两个表的函数 concat_2tables
  2. 实现递归函数 concatenateTables:通过 unpack 分割表列表,然后调用 concat_2tables 连接 table1restTableList
t1 = {1, 2, 3}
t2 = {4, 5}
t3 = {6}

concat_2tables = function(table1, table2)
    len = table.getn(table1)
    for key, val in pairs(table2) do
        table1[key+len] = val
    end
    return table1
end

concatenateTables = function(tableList)
    if tableList == nil then
        return  nil
    elseif table.getn(tableList) == 1 then
        return  tableList[1]
    else
        table1 = tableList[1]
        restTableList = {unpack(tableList, 2)}
        return concat_2tables(table1, concatenateTables(restTableList))
    end
end

tt = {t1, t2, t3}
t = concatenateTables(tt)
2015-10-23 07:01:00
stackoverflow用户2507567
stackoverflow用户2507567

如果你想要将一个已存在的表连接到一个新表上,这是最简洁的做法:

local t = {3, 4, 5}
local concatenation = {1, 2, table.unpack(t)}

虽然我不确定这个方法的性能如何。

2019-01-24 17:11:23
stackoverflow用户17935971
stackoverflow用户17935971
-- Lua 5.1+
function TableAppend(t1, t2)
    -- 一个数值for循环比pairs更快,但它只能得到t2的连续部分
    for i = 1, #t2 do
        t1[#t1 + 1] = t2[i] -- 这比table.insert稍微快一点
    end

    -- 此循环获取非连续部分(例如['a'] = 1),如果存在的话
    local k, v = next(t2, #t2 ~= 0 and #t2 or nil)
    while k do
        t1[k] = v -- 如果索引k已经存在于t1中,则会被重写
        k, v = next(t2, k)
    end
end
2022-01-14 19:45:16
stackoverflow用户12968803
stackoverflow用户12968803

使用 table.concat:

http://lua-users.org/wiki/TableLibraryTutorial

> = table.concat({ 1, 2, "three", 4, "five" })
12three4five
> = table.concat({ 1, 2, "three", 4, "five" }, ", ")
1, 2, three, 4, five
> = table.concat({ 1, 2, "three", 4, "five" }, ", ", 2)
2, three, 4, five
> = table.concat({ 1, 2, "three", 4, "five" }, ", ", 2, 4)
2, three, 4
2022-02-20 12:58:29
stackoverflow用户12136236
stackoverflow用户12136236

编辑


这里有一个更好的解决方案,另一个解决方案容易覆盖数值键,使用方式仍然相同:

function merge(...)
  local temp = {}
  local index = 1
  local result = {}

  math.randomseed(os.time())

  for i, tbl in ipairs({ ... }) do
    for k, v in pairs(tbl) do
      if type(k) == 'number' then
        -- 随机化数字键
        k = math.random() * i * k
      end

      temp[k] = v
    end
  end

  for k, v in pairs(temp) do
    if type(k) == "number" then
        -- 将数字键按顺序排序
      if result[index] then
        index = index + 1
      end

      k = index
    end

    result[k] = v
  end

  return result
end

原始文本


有一点晚了,但这对我来说似乎是有效的:

function concat(...)
  local result = {}

  for i, tbl in ipairs({...}) do
    for k, v in pairs(tbl) do
      if type(k) ~= "number" then
        result[k] = v
      else
        result[i] = v
      end
    end
  end

  return result
end

它可能有点复杂,但它接受无限数量的参数,并且适用于键值对和常规“数组”(以数字作为键)。 这是一个示例

2022-08-04 16:11:34
stackoverflow用户9234374
stackoverflow用户9234374

我喜欢@Weeve Ferrelaine在答案中的简单性,但改变可能会导致许多问题,并且一般来说是不可取的。

无改变的版本。
---@param t1 {}
---@param t2 {}
function TableConcat(t1,t2)
    local tOut = {}

    for i = 1, #t1 do
        tOut[i] = t1[i]
    end

    for i = #t1+1, #t1 + #t2 do
        tOut[i] = t2[i-#t1]
    end

    return tOut
end
原实现,会改变t1。
function TableConcat(t1,t2)
    for i=1,#t2 do
        t1[#t1+1] = t2[i]
    end
    return t1
end
2022-11-24 12:00:31