Logo

Programming-Idioms

This language bar is your friend. Select your favorite languages!

Idiom #247 Filter list in-place

Remove all the elements from list x that don't satisfy the predicate p, without allocating a new list.
Keep all the elements that do satisfy p.

For languages that don't have mutable lists, refer to idiom #57 instead.

del_count = 0
for i in range(len(x)):
    if not p(x[i - del_count]):
        del x[i - del_count]
        del_count += 1
#include <list>
#include <functional>
std::list<Foo> x;
x.remove_if(std::not_fn(p));
#include <functional>
std::erase_if(x, std::not_fn(p));
x.RemoveAll(item => !p(item));
x.retainWhere((e) => p);
x = pack(x,.not.p())
j := 0
for i, v := range x {
	if p(v) {
		x[j] = x[i]
		j++
	}
}
x = x[:j]
j := 0
for i, v := range x {
	if p(v) {
		x[j] = x[i]
		j++
	}
}
for k := j; k < len(x); k++ {
	x[k] = nil
}
x = x[:j]
func Filter[S ~[]T, T any](x *S, p func(T) bool) {
	j := 0
	for i, v := range *x {
		if p(v) {
			(*x)[j] = (*x)[i]
			j++
		}
	}
	var zero T
	for k := j; k < len(*x); k++ {
		(*x)[k] = zero
	}
	*x = (*x)[:j]
}
import "slices"
del := func(t *T) bool { return !p(t) }

x = slices.DeleteFunc(x, del)
for (const [key, value] of x.entries()) {
	if (!p(value)) x.splice(key, 1);
}
x = x.filter((e) => p(e));
x.removeIf(p.negate());
uses classes;
for i := x.count-1 downto 0 do
  if not p(x.items[i]) then x.delete(i);
@x = grep { p($_) } @x;
x.select!(&:p)
let mut j = 0;
for i in 0..x.len() {
    if p(x[i]) {
        x[j] = x[i];
        j += 1;
    }
}
x.truncate(j);
x.retain(p);

New implementation...