package sliceutil // AppendFilter takes two slice, 's' as source and 'd' as destination // and a predicate function, then applies it to each element of 's', // when 'p' returns true it appends the element into d, otherwise omit it. func AppendFilter[T any](s []T, d *[]T, p func(T) bool) { for _, e := range s { if p(e) { *d = append(*d, e) } } } // AssignFilter takes two slice, 's' as source and 'd' as destination // and a predicate function, then applies it to each element of 's'. // 'd' slice will have the same capacity of 's' but starts with 0 length. // When 'p' returns true it appends the element into d, otherwise omit it. func AssignFilter[T any](s []T, d *[]T, p func(T) bool) { if cap(*d) == 0 { *d = make([]T, 0, len(s)) } for _, e := range s { if p(e) { *d = append(*d, e) } } } // DisposeFilter takes two slice, 's' as source and 'd' as destination // and a predicate function, then applies it to each element of 's'. // 'd' slice will share the exact same memory address of 's'. // When 'p' returns true it appends the element into d, otherwise omit it. // Then disposes the 's'. IMPORTANT: 's' cannot be used again. func DisposeFilter[T any](s []T, d *[]T, p func(T) bool) { *d = s[:0] for _, e := range s { if p(e) { *d = append(*d, e) } } var NIL T for i := len(*d); i < len(s); i++ { s[i] = NIL } } // InPlaceFilter takes a slice and a predicate function, then applies it to each element of 's'. // When 'p' returns true it assign the value to the last index plus one where p was true, otherwise omit it. func InPlaceFilter[T any](s *[]T, p func(T) bool) { i := 0 for _, e := range *s { if p(e) { (*s)[i] = e i++ } } *s = (*s)[:i] } // Filter takes a slice and a predcate function, then applies it to each element of 's'. // When 'p' returns true it appends the value to the output slice. func Filter[T any](s []T, p func(T) bool) []T { o := make([]T, 0, len(s)) for _, e := range s { if p(e) { o = append(o, e) } } return o }