table.insert覆盖现有索引

时间:2013-12-03 15:15:06

标签: lua lua-table

解答:只对序列(数组/列表)使用table。*函数(只有从1开始的连续整数键的表)。他们的行为在非类似数组的表上是未定义的:它们可能会或可能不会像您期望的那样工作。


在Lua 5.1中,如果索引已经存在于表中,table.insert(t,index,value)应该向上移动值,对吗?

但它并不总是如此:

local t = {}
table.insert( t, 4, 5 )
table.insert( t, 5, 6 )
table.insert( t, 4, 4 ) -- this erase the value 5 at key 4
-- t[4] = 4, t[5] = 6, t[6] = nil

local t = {}
table.insert( t, 1 )
table.insert( t, 2 )
table.insert( t, 3 )

table.insert( t, 6, 7 )
table.insert( t, 6, 6 ) -- this erase the value 7 at key 6
-- t[6] = 6, t[7] = nil

但是:

local t = {}
table.insert( t, 1 ) -- these two lines were added
table.insert( t, 2 ) 
table.insert( t, 4, 5 )
table.insert( t, 5, 6 )
table.insert( t, 4, 4 ) -- now it moves the values up
-- t[4] = 4, t[5] = 5, t[6] = 5

local t = {}
table.insert( t, 1 )
table.insert( t, 2 )
table.insert( t, 3 )
table.insert( t, 4 ) -- this line was added
table.insert( t, 6, 7 )
table.insert( t, 6, 6 ) -- now it moves the values up
-- t[6] = 6, t[7] = 7

这在LuaForWindows命令行中也是如此,以及运行lua脚本(CraftStudio)的应用程序,两者都使用Lua 5.1。

似乎发生在

  • (条目数)< index(第一个例子)
  • (条目数)< index-1(第二个例子)

那么,这是一个预期的行为,Lua 5.1的错误吗? 还有另一个公式来预测这是否会发生?

非常感谢

1 个答案:

答案 0 :(得分:4)

表只有在其索引是连续的时才是列表:t [1],t [2],t [3],... t [i],... t [N]是非零的我从1到N.你的代码使用一个表作为关联数组(在C ++中映射,在Python中使用字典),因此表操作不起作用(实际上,它们有时可能有效,因为它是未定义的行为)。从Lua 5.1参考手册:

  

表库中的大多数函数都假定表格代表   数组或列表。

不幸的是,ref手册没有明确定义“数组或列表”,但是浏览参考数据的ref man指出了两个简单的规则足以成为“常规”或“普通”数组:没有n的值为t [i]对于i = 1到N.

对于i = 1到N,您可能最好创建一个t [i] = 0的表,其中N大于您在该函数调用中所期望的任何值(例如,某些其他表中的最大值)。完成插入后,您可以将剩余的所有剩余t [i] = 0设置为nil,但只有在您不需要表操作时才能这样做。

你可以做的另一件事是,如果你发现应该在我之前插入一个项目,检查t [i-1]是否为零;如果是,则将其设置为0或-1或表示“虚拟”的某个值。对i-2等重复此检查。