迭代时安全地从数组表中删除项目 [英] Safely remove items from an array table while iterating

查看:98
本文介绍了迭代时安全地从数组表中删除项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此问题类似于

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆