Skip to content

Instantly share code, notes, and snippets.

@harrison3000
Created May 14, 2022 12:44
Show Gist options
  • Save harrison3000/16a5b2c8350cd9bdd3b3e0815089a0ee to your computer and use it in GitHub Desktop.
Save harrison3000/16a5b2c8350cd9bdd3b3e0815089a0ee to your computer and use it in GitHub Desktop.
Simple generic slice filtering function for Golang 1.18+
package slicefilter
// FilterSliceFunc filters the input slice based on a pass function
// and returns the filtered slice
// it filters inplace and modifies the input slice, so be careful!
func FilterSliceFunc[S any](in []S, pass func(S) bool) []S {
outIdx := 0
for _, v := range in {
if !pass(v) {
continue
}
in[outIdx] = v
outIdx++
}
return in[:outIdx]
}
package slicefilter
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestFilter(t *testing.T) {
a := []int{1, 2, 5, 4, 1, 2, 3, 6, 7, 0, 1, 4, 0, 1, 4, 1}
b := []int{2, 5, 4, 2, 3, 6, 7, 0, 4, 0, 4}
res := FilterSliceFunc(a, func(v int) bool {
return v != 1
})
assert.Equal(t, b, res)
}
func TestEmpty(t *testing.T) {
a := []int{2, 5, 4, 1, 2, 3, 6, 1, 7, 0, 1, 4, 0, 1, 4, 1}
b := []int{}
res := FilterSliceFunc(a, func(int) bool {
return false
})
assert.Equal(t, b, res)
}
func BenchmarkNop(b *testing.B) {
a := []int{2, 5, 4, 1, 2, 3, 6, 1, 7, 0, 1, 4, 0, 1, 4, 1}
for i := 0; i < b.N; i++ {
FilterSliceFunc(a, func(int) bool {
return true
})
}
}
func BenchmarkFilter(b *testing.B) {
for i := 0; i < b.N; i++ {
a := []int{75, 13, 46, 88, 74, 58, 28, 19, 48, 51,
73, 10, 94, 52, 35, 9, 71, 1, 41, 50,
37, 60, 98, 86, 17, 30, 27, 55, 82, 100,
23, 90, 33, 38, 8, 24, 7, 57, 56, 54,
77, 39, 83, 70, 2, 44, 3, 18, 78, 32,
95, 65, 34, 76, 84, 14, 97, 85, 80, 5,
42, 89, 79, 68, 25, 49, 93, 99, 59, 11,
69, 4, 66, 96, 87, 61, 92, 43, 40, 20,
67, 53, 47, 72, 63, 91, 16, 12, 29, 6,
21, 81, 64, 15, 22, 62, 36, 31, 26, 45}
FilterSliceFunc(a, func(v int) bool {
return v < 50
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment