[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: ipairs_remove - remove items from array while iterating it
- From: Dirk Laurie <dirk.laurie@...>
- Date: Sun, 3 Nov 2013 06:50:18 +0200
2013/11/2 Philipp Janda <siffiejoe@gmx.net>:
> Maybe a for loop iterator is the wrong interface for this particular
> problem. Maybe something like `table.foreachi_rm()`?
> Or the "second loop" method in form of a `compact()` function ...
>
> local n = #t
> for i = 1, n do
> if should_remove( t[ i ] ) then t[ i ] = nil end
> end
> compact( t, n ) -- or compact( t, 1, n )
Microlight has 'ifilter'.
--- filter a array using a predicate.
-- If `pred` is absent, then we provide a default which
-- filters out any `false` values.
-- @param t a table
-- @param pred the predicate function
-- @param ... any extra arguments to the predicate
-- @return a array such that `pred(t[i])` is true
$ lua -l ml
> t = { "a", "b", "c", "d", "e" }
> print(ml.tstring(ml.ifilter(t, function(x) return x~='c' end )))
{"a","b","d","e"}
The code (some Microlight idiosyncrasies removed) is very
straightforward:
function ifilter(t,pred,...)
local res,k = setmetatable({},getmetatable(t)), 1
pred = pred or true
for i = 1,#t do
if pred(t[i],...) then
res[k] = t[i]
k = k + 1
end
end
return res
end
This is O(n) and does not destroy the original table.
You can do that yourself by assigning the result of
ifilter to it.