原始帖子
鉴于Lua中没有内置函数,我正在寻找一个允许我将表附加在一起的函数。我已经google了很多,并尝试了我偶然发现的所有解决方案,但似乎都没有正常工作。
场景如下:我在应用程序中使用Lua。应用程序的内部命令以表格的形式返回值列表。
我要做的是在循环中递归调用该命令,并将返回的值再次以表的形式附加到先前迭代的表中。
修改
对于将来遇到这篇文章的人,请注意@gimf发布的内容。由于Lua中的Tables与其他任何内容一样(即使在列表上下文中),因此没有真正正确的方法将一个表附加到另一个表。最接近的概念是合并表格。有关这方面的帮助,请参阅帖子“Lua - merge tables?”。
答案 0 :(得分:27)
过于复杂的答案很多?
这是我的实施:
function TableConcat(t1,t2)
for i=1,#t2 do
t1[#t1+1] = t2[i]
end
return t1
end
答案 1 :(得分:5)
要一起添加两个表,请执行此操作
ii=0
for i=#firsttable, #secondtable+#firsttable do
ii=ii+1
firsttable[i]=secondtable[ii]
end
使用第一个表作为您要添加的变量,因为代码会按顺序将第二个表添加到第一个表的末尾。
i
是表格或列表的起始编号。#secondtable+#firsttable
即将结束。它从您要添加到的第一个表的末尾开始,并在for
循环中的第二个表的末尾结束,因此它适用于任何大小的表或列表。
答案 2 :(得分:4)
一般来说,连接任意表的概念在Lua中没有意义,因为单个键只能有一个值。
在某些特殊情况下,连接确实有意义。其中一个是包含简单数组的表,这可能是用于返回结果列表的函数的自然结果。
在这种情况下,你可以写:
-- return a new array containing the concatenation of all of its -- parameters. Scaler parameters are included in place, and array -- parameters have their values shallow-copied to the final array. -- Note that userdata and function values are treated as scalar. 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在评论中所观察到的那样,我无法从...
中正确提取每个参数的实际值。我也无法从函数中返回合并表。这就是我在答案框中编码而不是完全测试代码的原因。
答案 3 :(得分:4)
一种做你想做的事的简单方法:
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
答案 4 :(得分:2)
如果要合并两个表,但需要结果表的深层副本,无论出于何种原因,请使用another SO question on merging tables中的合并以及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表而言,简单的“连接”表概念是没有意义的。 的)强>
答案 5 :(得分:2)
还有一种方法:
for _,v in ipairs(t2) do
table.insert(t1, v)
end
在我看来,它是最易读的 - 它遍历第二个表并将其值附加到第一个,故事结尾。好奇的是它的速度与上面的显式索引[]之间的差距
答案 6 :(得分:1)
这是我已经完成的类似于RBerteig的实现,但是使用隐藏参数 arg ,当函数接收到可变数量的参数时,该参数可用。就个人而言,我认为这比选择语法更具可读性。
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
答案 7 :(得分:1)
这是我的实现,用于连接一组纯整数索引表,FYI。
concat_2tables
另一个递归函数concatenateTables
:按unpack
拆分表格列表,并调用concat_2tables
以连接table1
和restTableList
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)
答案 8 :(得分:0)
如果要将现有表连接到新表,这是最简洁的方法:
local t = {3, 4, 5}
local concatenation = {1, 2, table.unpack(t)}
尽管我不确定这在性能方面有多好。