[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: filter an array in place
- From: Steve Litt <slitt@...>
- Date: Fri, 14 Jan 2011 00:22:22 -0500
On Thursday 13 January 2011 23:12:40 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?
I'd have a variable called goes_here initialized to 1. Each iteration of your
loop increments goes_here UNLESS tab[goes_here] meets the conditon. On each
iteration, copy tab[index] to tab[goes_here]. At the end goes_here indicates
either the last valid entry or the first invalid one.
Obviously I haven't thought all of this out, but you know what I mean, and it
will do it without deleting or nilling a key, and it should be pretty darn
fast because you do it in place and loop only once.
SteveT
Steve Litt
Recession Relief Package
http://www.recession-relief.US
Twitter: http://www.twitter.com/stevelitt