Logo

Programming-Idioms

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

Idiom #57 Filter list

Create the list y containing the items from the list x that satisfy the predicate p. Respect the original ordering. Don't modify x in-place.

func filter[S ~[]T, T any](x S, p func(T) bool) S {
	var y S
	for _, v := range x {
		if p(v) {
			y = append(y, v)
		}
	}
	return y
}

filter is a generic function with a type parameter T
import "slices"
del := func(t *T) bool { return !p(t) }

y := slices.DeleteFunc(slices.Clone(x), del)

Elements have type T.
del (discard) is the opposite of the function p (keep)

We must clone x before deleting some contents.
y := make([]T, 0, len(x))
for _, v := range x{
	if p(v){
		y = append(y, v)
	}
}

For item type T.
Note that this allocates memory for the new slice y.
Warning: y is allocated with as much memory as x, which may in some cases be wasteful.
n := 0
for _, v := range x {
	if p(v) {
		n++
	}
}
y := make([]T, 0, n)
for _, v := range x {
	if p(v) {
		y = append(y, v)
	}
}

This makes 2 passes: one to count the number n of elements to be kept, and one to copy the elements in the target slice created with the correct size n.
This is efficient if p is cheap and x is small.
for Item of X loop
   if P (Item) then
      Y.Append (Item);
   end if;
end loop;

New implementation...