Lua 从数组中间删除值时会发生什么情况?
如果我有这样一个数组:Lua 从数组中间删除值时会发生什么情况?,lua,Lua,如果我有这样一个数组: localarray={'foo','bar','baz'} 我删除了第二个元素,如下所示: 数组[2]=nil 这会将数组[3]和任何较大的索引发送到表的哈希部分吗?或者它只是在数组部分留下一个洞?它将添加另一个边框 这有一些影响: 您不能再使用ipairs获取所有元素,因为ipairs将在第一个边框处停止 长度操作符#将不再提供该表中的元素数,因为它可能返回任何边框 table.concat将在“concat”的表中索引2处引发错误无效值(nil) 表库中的某些函
localarray={'foo','bar','baz'}
我删除了第二个元素,如下所示:
数组[2]=nil
这会将
数组[3]
和任何较大的索引发送到表的哈希部分吗?或者它只是在数组部分留下一个洞?它将添加另一个边框
这有一些影响:
ipairs
获取所有元素,因为ipairs
将在第一个边框处停止#
将不再提供该表中的元素数,因为它可能返回任何边框table.concat
将在“concat”的表中索引2处引发错误无效值(nil)newarray = {}
for i = 1, #array do
if array[i] then
newarray[ #newarray ] = array[i]
end
end
或者,使用多个赋值将它们全部向下移动一个位置,以触发条目(索引3到2,索引2到3…),将该nil
保留为最终条目,以便一切按预期进行
for i = 1, #array do
if not array[i] then
array[i], array[i+1] = array[i+1], array[i]
end
end
那会留下一个洞。因此存在:
table.remove()
你必须使你的工具专业化。
例如,可以处理它的tprint()
tprint=function(tab,...)
local args={...}
local start=args[1]
local stop=args[2]
if type(args[1])=='number' and type(args[2])=='number' then
warn('Using numbers for table print out')
for i=start,stop do
io.write(string.format('%d = %s\n',i,tab[i])):flush()
if start==stop then return tab[i] end
end
else
warn('Using pairs() for table print out')
for key,value in pairs(tab) do
io.write(string.format('%s = %s\n',key,value)):flush()
end
end
end
比你能做的更多,比如
>tprint(arg)
Lua warning: Using pairs() for table print out
1 = -W
2 = -i
3 = -e
4 = dofile('/root/lua/tprint.lua')
0 = /root/bin/lua
1618128658 = It is alive!!!
1618129059 = function: 0x566bf0f0
1618129084 = function: 0x566bfba0
1618128894 = tprint
>tprint(arg,1618128658,1618128658)
Lua warning: Using numbers for table print out
1618128658 = It is alive!!!
It is alive!!!
…或从0到4的序列
>tprint(arg,0,4)
Lua warning: Using numbers for table print out
0 = /root/bin/lua
1 = -W
2 = -i
3 = -e
4 = dofile('/root/lua/tprint.lua')
请注意,长度运算符将返回任何边框。它不一定是表中元素的数量,除非表是一个序列。它在很多情况下都会起作用,但在很多情况下不会起作用。您的第二个代码段在
{1,nil,3,nil}
或多个后续nil的简单情况下失败。因为你也会把nil值移回原处是的,我假设你会在删除一个条目后直接清除列表,而不是等待多个洞累积。但是,其他人可能需要知道这一点。如果您只想删除单个元素,请使用table。如果是您的列表,则删除会为您进行转换,并且该选项可用,当然。放弃nil
&多重赋值<代码>删除()
将更有效。然而,问题是关于列表中的nil
条目的。因此,如果你的列表被一个你无法控制的函数打孔,那么就使用有效的方法。实际上,问题是如果你在一个序列中引入一个间隙会发生什么,而不是如何消除它。没关系,不是来争论的;)如果你不想让你的表穿孔,你可能应该使用元表来防止穿孔。抱歉@Pieget-第3点取决于你如何使用concat
-我相信concat就像一把解剖刀,用来解剖数字键-例如:table.concat(arg',0,0)
准确地说出了我想要的;-)-而且,用几个不同的键块序列,你或我们可以找到我们想要的任何东西want@koyaanisqatsi这是OP示例数组的错误消息。您可以提供一个可选的开始和结束索引来解决间隙问题,但对于任何包含nil值的范围,该索引都将失败table.concat(arg,,,0,0)
是无意义的,根据第4章使用arg[0]
,从这里开始,lua有一个数组部分和散列部分。根据这篇文章,lua没有使用“纯”关联数组,尽管在5.0之前可能是这样。我的问题更多的是lua将如何处理这个洞,它是否只是把它作为一个洞(零)?或者它会将更大的索引重新分配到散列部分吗?对不起,我没有想起这篇文章。所以你的问题是关于Lua的内部运作,而不是脚本中的后果。我建议你在邮件列表中询问,Lua的开发人员会不时在这里回答问题,但直接与他们联系可能更成功。我认为这并不能真正回答问题。此外,这是相当特殊的,可能不容易理解为初学者。它引入了许多与问题无关的噪音`单个元素的table.concat可以简单地由表索引和到字符串imhoYes的隐式或显式转换来替换-我同意-并将(正确;-)concat替换为tab[I]