mirror of
https://github.com/rjNemo/underscore
synced 2026-06-06 02:26:42 +00:00
feat: add TakeWhile and DropWhile functions (#42)
- Add TakeWhile: returns elements while predicate is true - Add DropWhile: drops elements while predicate is true - Comprehensive tests including edge cases - Benchmarks included Resolves Issue 14 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
parent
3617c2de8f
commit
b35a87e50c
4 changed files with 142 additions and 0 deletions
15
dropwhile.go
Normal file
15
dropwhile.go
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
package underscore
|
||||
|
||||
// DropWhile drops elements from the beginning of the slice while the predicate returns true.
|
||||
// It returns the remaining elements starting from the first element where the predicate returns false.
|
||||
func DropWhile[T any](values []T, predicate func(T) bool) []T {
|
||||
for i, v := range values {
|
||||
if !predicate(v) {
|
||||
res := make([]T, len(values)-i)
|
||||
copy(res, values[i:])
|
||||
return res
|
||||
}
|
||||
}
|
||||
// All elements satisfy predicate, return empty slice
|
||||
return []T{}
|
||||
}
|
||||
55
dropwhile_test.go
Normal file
55
dropwhile_test.go
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
package underscore_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
u "github.com/rjNemo/underscore"
|
||||
)
|
||||
|
||||
func TestDropWhile(t *testing.T) {
|
||||
nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
|
||||
result := u.DropWhile(nums, func(n int) bool { return n < 5 })
|
||||
assert.Equal(t, []int{5, 6, 7, 8, 9}, result)
|
||||
}
|
||||
|
||||
func TestDropWhileEmpty(t *testing.T) {
|
||||
result := u.DropWhile([]int{}, func(n int) bool { return n < 5 })
|
||||
assert.Equal(t, []int{}, result)
|
||||
}
|
||||
|
||||
func TestDropWhileNoneMatch(t *testing.T) {
|
||||
nums := []int{5, 6, 7, 8, 9}
|
||||
result := u.DropWhile(nums, func(n int) bool { return n < 5 })
|
||||
assert.Equal(t, []int{5, 6, 7, 8, 9}, result)
|
||||
}
|
||||
|
||||
func TestDropWhileAllMatch(t *testing.T) {
|
||||
nums := []int{1, 2, 3, 4}
|
||||
result := u.DropWhile(nums, func(n int) bool { return n < 10 })
|
||||
assert.Equal(t, []int{}, result)
|
||||
}
|
||||
|
||||
func TestDropWhileSingleElement(t *testing.T) {
|
||||
result := u.DropWhile([]int{5}, func(n int) bool { return n < 10 })
|
||||
assert.Equal(t, []int{}, result)
|
||||
}
|
||||
|
||||
func TestDropWhileStrings(t *testing.T) {
|
||||
words := []string{"apple", "banana", "cherry", "date"}
|
||||
result := u.DropWhile(words, func(s string) bool { return len(s) < 6 })
|
||||
assert.Equal(t, []string{"banana", "cherry", "date"}, result)
|
||||
}
|
||||
|
||||
func BenchmarkDropWhile(b *testing.B) {
|
||||
nums := make([]int, 1000)
|
||||
for i := range nums {
|
||||
nums[i] = i
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
u.DropWhile(nums, func(n int) bool { return n < 500 })
|
||||
}
|
||||
}
|
||||
17
takewhile.go
Normal file
17
takewhile.go
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
package underscore
|
||||
|
||||
// TakeWhile returns elements from the beginning of the slice while the predicate returns true.
|
||||
// It stops at the first element where the predicate returns false.
|
||||
func TakeWhile[T any](values []T, predicate func(T) bool) []T {
|
||||
for i, v := range values {
|
||||
if !predicate(v) {
|
||||
res := make([]T, i)
|
||||
copy(res, values[:i])
|
||||
return res
|
||||
}
|
||||
}
|
||||
// All elements satisfy predicate
|
||||
res := make([]T, len(values))
|
||||
copy(res, values)
|
||||
return res
|
||||
}
|
||||
55
takewhile_test.go
Normal file
55
takewhile_test.go
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
package underscore_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
u "github.com/rjNemo/underscore"
|
||||
)
|
||||
|
||||
func TestTakeWhile(t *testing.T) {
|
||||
nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
|
||||
result := u.TakeWhile(nums, func(n int) bool { return n < 5 })
|
||||
assert.Equal(t, []int{1, 2, 3, 4}, result)
|
||||
}
|
||||
|
||||
func TestTakeWhileEmpty(t *testing.T) {
|
||||
result := u.TakeWhile([]int{}, func(n int) bool { return n < 5 })
|
||||
assert.Equal(t, []int{}, result)
|
||||
}
|
||||
|
||||
func TestTakeWhileNoneMatch(t *testing.T) {
|
||||
nums := []int{5, 6, 7, 8, 9}
|
||||
result := u.TakeWhile(nums, func(n int) bool { return n < 5 })
|
||||
assert.Equal(t, []int{}, result)
|
||||
}
|
||||
|
||||
func TestTakeWhileAllMatch(t *testing.T) {
|
||||
nums := []int{1, 2, 3, 4}
|
||||
result := u.TakeWhile(nums, func(n int) bool { return n < 10 })
|
||||
assert.Equal(t, []int{1, 2, 3, 4}, result)
|
||||
}
|
||||
|
||||
func TestTakeWhileSingleElement(t *testing.T) {
|
||||
result := u.TakeWhile([]int{5}, func(n int) bool { return n < 10 })
|
||||
assert.Equal(t, []int{5}, result)
|
||||
}
|
||||
|
||||
func TestTakeWhileStrings(t *testing.T) {
|
||||
words := []string{"apple", "banana", "cherry", "date"}
|
||||
result := u.TakeWhile(words, func(s string) bool { return len(s) < 6 })
|
||||
assert.Equal(t, []string{"apple"}, result)
|
||||
}
|
||||
|
||||
func BenchmarkTakeWhile(b *testing.B) {
|
||||
nums := make([]int, 1000)
|
||||
for i := range nums {
|
||||
nums[i] = i
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
u.TakeWhile(nums, func(n int) bool { return n < 500 })
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue