Added some more find functions
All checks were successful
ci / deploy (push) Successful in 1m5s

This commit is contained in:
Leon Mika 2026-09-05 09:40:33 +10:00
parent e33476ea5c
commit 5586ab7464
2 changed files with 150 additions and 1 deletions

View file

@ -20,6 +20,16 @@ func FirstWhere[T any](ts []T, predicate func(t T) bool) T {
return zeroT return zeroT
} }
// FirstIndexWhere returns the index of the first element in the slice that satisfies the predicate. An empty slice will return -1
func FirstIndexWhere[T any](ts []T, predicate func(t T) bool) int {
for i, t := range ts {
if predicate(t) {
return i
}
}
return -1
}
func FindWhere[T any](ts []T, predicate func(t T) bool) (T, bool) { func FindWhere[T any](ts []T, predicate func(t T) bool) (T, bool) {
var zeroT T var zeroT T
@ -41,3 +51,26 @@ func FindWithIndexWhere[T any](ts []T, predicate func(t T) bool) (T, int, bool)
} }
return zeroT, 0, false return zeroT, 0, false
} }
// AnyWhere returns true if any element in the slice satisfies the predicate. An empty slice will return false
func AnyWhere[T any](ts []T, predicate func(t T) bool) bool {
for _, t := range ts {
if predicate(t) {
return true
}
}
return false
}
// AllWhere returns true if all the element in the slice satisfies the predicate. An empty slice will return false
func AllWhere[T any](ts []T, predicate func(t T) bool) bool {
if len(ts) == 0 {
return false
}
for _, t := range ts {
if !predicate(t) {
return false
}
}
return true
}

View file

@ -1,9 +1,11 @@
package moslice_test package moslice_test
import ( import (
"lmika.dev/pkg/modash/moslice" "strings"
"testing" "testing"
"lmika.dev/pkg/modash/moslice"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -23,3 +25,117 @@ func TestContains(t *testing.T) {
assert.False(t, moslice.Contains(strs, "bla")) assert.False(t, moslice.Contains(strs, "bla"))
}) })
} }
func TestFirstWhere(t *testing.T) {
var (
ints = []int{1, 2, 3, 4, 5}
strs = []string{"foo", "bar", "baz"}
)
t.Run("should return the first element that satisfies the predicate", func(t *testing.T) {
assert.Equal(t, 2, moslice.FirstWhere(ints, func(x int) bool { return x%2 == 0 }))
assert.Equal(t, "bar", moslice.FirstWhere(strs, func(x string) bool { return strings.HasPrefix(x, "b") }))
})
t.Run("should return the element if the first element satisfies the predicate", func(t *testing.T) {
assert.Equal(t, 1, moslice.FirstWhere(ints, func(x int) bool { return x%2 == 1 }))
assert.Equal(t, "foo", moslice.FirstWhere(strs, func(x string) bool { return strings.HasPrefix(x, "f") }))
})
t.Run("should return the zero value if no element satisfies the predicate", func(t *testing.T) {
assert.Equal(t, 0, moslice.FirstWhere(ints, func(x int) bool { return x > 10 }))
assert.Equal(t, "", moslice.FirstWhere(strs, func(x string) bool { return strings.HasPrefix(x, "z") }))
})
t.Run("should return the zero value if the passed in slice is empty", func(t *testing.T) {
assert.Equal(t, 0, moslice.FirstWhere([]int{}, func(x int) bool { return true }))
})
t.Run("should return the zero value if the passed in slice is nil", func(t *testing.T) {
assert.Equal(t, 0, moslice.FirstWhere(nil, func(x int) bool { return true }))
})
}
func TestFirstIndexWhere(t *testing.T) {
var (
ints = []int{1, 2, 3, 4, 5}
strs = []string{"foo", "bar", "baz"}
)
t.Run("should return the index of the first element that satisfies the predicate", func(t *testing.T) {
assert.Equal(t, 1, moslice.FirstIndexWhere(ints, func(x int) bool { return x%2 == 0 }))
assert.Equal(t, 1, moslice.FirstIndexWhere(strs, func(x string) bool { return strings.HasPrefix(x, "b") }))
})
t.Run("should return 0 if the first element satisfies the predicate", func(t *testing.T) {
assert.Equal(t, 0, moslice.FirstIndexWhere(ints, func(x int) bool { return x%2 == 1 }))
assert.Equal(t, 0, moslice.FirstIndexWhere(strs, func(x string) bool { return strings.HasPrefix(x, "f") }))
})
t.Run("should return -1 if no element satisfies the predicate", func(t *testing.T) {
assert.Equal(t, -1, moslice.FirstIndexWhere(ints, func(x int) bool { return x > 10 }))
assert.Equal(t, -1, moslice.FirstIndexWhere(strs, func(x string) bool { return strings.HasPrefix(x, "z") }))
})
t.Run("should return -1 if the passed in slice is empty", func(t *testing.T) {
assert.Equal(t, -1, moslice.FirstIndexWhere([]int{}, func(x int) bool { return true }))
})
t.Run("should return -1 if the passed in slice is nil", func(t *testing.T) {
assert.Equal(t, -1, moslice.FirstIndexWhere(nil, func(x int) bool { return true }))
})
}
func TestAnyWhere(t *testing.T) {
var (
ints = []int{1, 2, 3, 4, 5}
strs = []string{"foo", "bar", "baz"}
)
t.Run("should return true if any element satisfies the predicate", func(t *testing.T) {
assert.True(t, moslice.AnyWhere(ints, func(x int) bool { return x%2 == 0 }))
assert.True(t, moslice.AnyWhere(strs, func(x string) bool { return strings.HasPrefix(x, "ba") }))
})
t.Run("should return false if no element satisfies the predicate", func(t *testing.T) {
assert.False(t, moslice.AnyWhere(ints, func(x int) bool { return x > 10 }))
assert.False(t, moslice.AnyWhere(strs, func(x string) bool { return strings.HasPrefix(x, "z") }))
})
t.Run("should return false if the passed in slice is empty", func(t *testing.T) {
assert.False(t, moslice.AnyWhere([]int{}, func(x int) bool { return true }))
})
t.Run("should return false if the passed in slice is nil", func(t *testing.T) {
assert.False(t, moslice.AnyWhere(nil, func(x int) bool { return true }))
})
}
func TestAllWhere(t *testing.T) {
var (
ints = []int{2, 4, 6}
strs = []string{"foo", "bar", "baz"}
)
t.Run("should return true if all elements satisfy the predicate", func(t *testing.T) {
assert.True(t, moslice.AllWhere(ints, func(x int) bool { return x%2 == 0 }))
assert.True(t, moslice.AllWhere(strs, func(x string) bool { return len(x) == 3 }))
})
t.Run("should return false if some elements do not satisfy the predicate", func(t *testing.T) {
assert.False(t, moslice.AllWhere(ints, func(x int) bool { return x > 3 }))
assert.False(t, moslice.AllWhere(strs, func(x string) bool { return strings.HasPrefix(x, "b") }))
})
t.Run("should return false if no elements satisfy the predicate", func(t *testing.T) {
assert.False(t, moslice.AllWhere(ints, func(x int) bool { return x > 10 }))
})
t.Run("should return false if the passed in slice is empty", func(t *testing.T) {
assert.False(t, moslice.AllWhere([]int{}, func(x int) bool { return true }))
})
t.Run("should return false if the passed in slice is nil", func(t *testing.T) {
assert.False(t, moslice.AllWhere(nil, func(x int) bool { return true }))
})
}