迭代时安全地从数组表中删除项目 [英] Safely remove items from an array table while iterating
问题描述
This question is similar to How can I safely iterate a lua table while keys are being removed but distinctly different.
给出一个Lua数组(表的键是从1
开始的连续整数的表),迭代此数组并删除一些可见的条目的最佳方法是什么??
Given a Lua array (table with keys that are sequential integers starting at 1
), what's the best way to iterate through this array and delete some of the entries as they are seen?
我在Lua数组表中有一个带有时间戳的条目数组.条目总是添加到数组的末尾(使用table.insert
).
I have an array of timestamped entries in a Lua array table. Entries are always added to the end of the array (using table.insert
).
local timestampedEvents = {}
function addEvent( data )
table.insert( timestampedEvents, {getCurrentTime(),data} )
end
我偶尔需要(按顺序)浏览此表并处理并删除某些条目:
I need to occasionally run through this table (in order) and process-and-remove certain entries:
function processEventsBefore( timestamp )
for i,stamp in ipairs( timestampedEvents ) do
if stamp[1] <= timestamp then
processEventData( stamp[2] )
table.remove( timestampedEvents, i )
end
end
end
不幸的是,以上方法的代码中断了迭代,跳过了某些条目.有没有比手动遍历索引更好的方法(更少的键入,但是仍然安全):
Unfortunately, the code above approach breaks iteration, skipping over some entries. Is there any better (less typing, but still safe) way to do this than manually walking the indices:
function processEventsBefore( timestamp )
local i = 1
while i <= #timestampedEvents do -- warning: do not cache the table length
local stamp = timestampedEvents[i]
if stamp[1] <= timestamp then
processEventData( stamp[2] )
table.remove( timestampedEvents, i )
else
i = i + 1
end
end
end
推荐答案
我将避免将table.remove
并遍历数组,一旦将不需要的条目设置为nil
,然后遍历该数组,并在必要时对其进行压缩.
I'd avoid table.remove
and traverse the array once setting the unwanted entries to nil
then traverse the array again compacting it if necessary.
这是我想到的代码,使用来自Mud答案的示例:
Here's the code I have in mind, using the example from Mud's answer:
local input = { 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p' }
local remove = { f=true, g=true, j=true, n=true, o=true, p=true }
local n=#input
for i=1,n do
if remove[input[i]] then
input[i]=nil
end
end
local j=0
for i=1,n do
if input[i]~=nil then
j=j+1
input[j]=input[i]
end
end
for i=j+1,n do
input[i]=nil
end
这篇关于迭代时安全地从数组表中删除项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!