[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: filter an array in place
- From: Axel Kittenberger <axkibe@...>
- Date: Fri, 14 Jan 2011 08:23:46 +0100
You must not change a table while iterating through it with for/ipairs/pairs.
While it might work with some reversal its still bad style can possibly break.
This will work instead:
local tab = {"a", "a", "c", "a", "d", "a" }
local len = #tab
local k = 1
while tab[k] do
if tab[k] == "a" then
table.remove(tab, k)
else
k = k + 1
end
end
for k, v in ipairs(tab) do print(k, v) end
print()
for k, v in pairs(tab) do print(k, v) end
On Fri, Jan 14, 2011 at 5:26 AM, Robert G. Jakabosky
<bobby@sharedrealm.com> wrote:
> On Thursday 13, Emmanuel Oga wrote:
>> Hello, I'm looking for the best proper way of doing this:
>>
>> local tab = {"a", "a", "c", "a", "d", "a" }
>>
>> for index, val in ipairs(tab) do
>> if val == "a" then -- could be any other complex condition
>> table.remove(tab, index)
>> end
>> end
>>
>> -- WRONG: tab = { "a", "c", "d" }, should be { "c", "d" }
>>
>> So removing elements from a container _while you are iterating it_ is
>> wrong in most languages. I'm looking for the nicest and proper way of
>> doing it.
>>
>> Two methods I came up with:
>>
>> 1) popping from the array and pushing to a new one if the condition is met.
>> 2) Iterating first, storing indexes to remove, then removing one by
>> one (compensating index offset as a result of each removed elements)
>>
>> http://pastie.org/1458808
>>
>> Is there any other more elegant way?
>
> process the list in reverse.
>
> for index=#tab,1,-1 do
> local var = tab[index]
> if val == "a" then -- could be any other complex condition
> table.remove(tab, index)
> end
> end
>
>
> --
> Robert G. Jakabosky
>
>