我对LUA有点陌生。因此,我有一个游戏,需要捕获实体并将其插入表中。可能同时发生的最大Entity表为14。因此,我读到基于数组的解决方案很好。
但是我看到即使我们删除一些值(例如从10个表值中删除并删除索引9处的值),表大小也会增加,当我要插入表号11时,它不会自动移动大小。
示例:
local Table = {"hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello"}
-- Current Table size = 10
-- Perform delete at index 9
Table[9] = nil
-- Have new Entity to insert
Table[#Table + 1] = "New Value"
-- The table size will grow by the time the game extend.
因此,对于这种情况,在插入新表值时具有零值的,内部数组为零的基于表的表是否会具有更好的性能,还是应该使用键移入表? 还是我应该坚持使用基于数组的表并在不使用表时执行完全清理?
答案 0 :(得分:0)
如果将表中的元素设置为nil,那么它只是作为数组中的“空洞”保留在那里。
tab = {1, 2, 3, 4}
tab[2] = nil
-- tab == {1, nil, 3, 4}
-- #tab is actually undefined and could be both 1 or 4 (or something completely unexpected)!
您需要做的是将字段设置为nil,然后移动以下所有字段以填补该漏洞。幸运的是,Lua为此提供了一个功能,即table.remove(table, index)
。
tab = {1, 2, 3, 4}
table.remove(tab, 2)
-- tab == {1, 3, 4}
-- #tab == 3
请记住,由于涉及大量内存访问,这可能会变得非常慢,因此,如果某天有几百万个元素,请不要应用此解决方案:)
答案 1 :(得分:0)
虽然table.remove(Table, 9)
可以完成您的工作(从“数组”表中删除字段并移动剩余字段以填补空缺),但您应该首先考虑使用“设置”表。
如果您:
-经常删除/添加元素
-不在乎他们的订单
-经常检查表格是否包含某个元素
然后选择“设置”表。像这样使用
local tab = {
["John"] = true,
["Jane"] = true,
["Bob"] = true,
}
您的元素将作为索引存储在表中。 使用
删除元素tab["Jane"] = nil
测试表是否包含带有
的元素if tab["John"] then
-- tab contains "John"
与数组表相比的优势:
-删除元素时,这将消除性能开销,因为其他元素将保持不变,并且不需要进行任何移位
-检查该表中是否存在元素(我认为这是该表的主要目的)也比使用数组表快,因为不再需要遍历所有元素来查找匹配项,而是使用哈希查找>
但是请注意,这种方法不允许您将重复值作为元素,因为表不能包含重复键。在这种情况下,您可以使用数字作为值来存储元素在您的集合中重复的次数,例如
local tab = {
["John"] = 1,
["Jane"] = 2,
["Bob"] = 35,
}
现在您有1个John,2个Janes和35个Bobs