From 040e112aa6791f91759d9360bd8347ce50d045d2 Mon Sep 17 00:00:00 2001 From: dudaodong Date: Thu, 9 Feb 2023 17:38:31 +0800 Subject: [PATCH] feat: add DropRight and DropWhile --- slice/slice.go | 51 +++++++++++++++++++++++++++++-------- slice/slice_example_test.go | 18 +++++++++++++ slice/slice_test.go | 19 +++++++++++--- 3 files changed, 75 insertions(+), 13 deletions(-) diff --git a/slice/slice.go b/slice/slice.go index f5a98b8..3f1e89e 100644 --- a/slice/slice.go +++ b/slice/slice.go @@ -6,7 +6,6 @@ package slice import ( "fmt" - "math" "math/rand" "reflect" "sort" @@ -559,24 +558,56 @@ func DeleteAt[T any](slice []T, start int, end ...int) []T { return slice } -// Drop creates a slice with `n` elements dropped from the beginning when n > 0, or `n` elements dropped from the ending when n < 0. +// Drop drop n elements from the start of a slice. // Play: https://go.dev/play/p/pJ-d6MUWcvK func Drop[T any](slice []T, n int) []T { size := len(slice) - if size == 0 || n == 0 { - return slice - } - - if math.Abs(float64(n)) >= float64(size) { + if size <= n { return []T{} } - if n < 0 { - return slice[0 : size+n] + if n <= 0 { + return slice } - return slice[n:size] + result := make([]T, 0, size-n) + + return append(result, slice[n:]...) +} + +// DropRight drop n elements from the end of a slice. +// Play: todo +func DropRight[T any](slice []T, n int) []T { + size := len(slice) + + if size <= n { + return []T{} + } + + if n <= 0 { + return slice + } + + result := make([]T, 0, size-n) + + return append(result, slice[:size-n]...) +} + +// DropWhile drop n elements from the start of a slice while predicate function returns true. +// Play: todo +func DropWhile[T any](slice []T, predicate func(item T) bool) []T { + i := 0 + + for ; i < len(slice); i++ { + if !predicate(slice[i]) { + break + } + } + + result := make([]T, 0, len(slice)-i) + + return append(result, slice[i:]...) } // InsertAt insert the value or other slice into slice at index. diff --git a/slice/slice_example_test.go b/slice/slice_example_test.go index 930001d..a2851f7 100644 --- a/slice/slice_example_test.go +++ b/slice/slice_example_test.go @@ -482,7 +482,25 @@ func ExampleDrop() { // Output: // [a b c] // [b c] + // [a b c] + // [] +} + +func ExampleDropRight() { + result1 := DropRight([]string{"a", "b", "c"}, 0) + result2 := DropRight([]string{"a", "b", "c"}, 1) + result3 := DropRight([]string{"a", "b", "c"}, -1) + result4 := DropRight([]string{"a", "b", "c"}, 4) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // [a b c] // [a b] + // [a b c] // [] } diff --git a/slice/slice_test.go b/slice/slice_test.go index bdfaca7..0391ba8 100644 --- a/slice/slice_test.go +++ b/slice/slice_test.go @@ -388,9 +388,22 @@ func TestDrop(t *testing.T) { assert.Equal([]int{}, Drop([]int{1, 2, 3, 4, 5}, 5)) assert.Equal([]int{}, Drop([]int{1, 2, 3, 4, 5}, 6)) - assert.Equal([]int{1, 2, 3, 4}, Drop([]int{1, 2, 3, 4, 5}, -1)) - assert.Equal([]int{}, Drop([]int{1, 2, 3, 4, 5}, -6)) - assert.Equal([]int{}, Drop([]int{1, 2, 3, 4, 5}, -6)) + assert.Equal([]int{1, 2, 3, 4, 5}, Drop([]int{1, 2, 3, 4, 5}, -1)) +} + +func TestDropRight(t *testing.T) { + assert := internal.NewAssert(t, "TestInterfaceSlice") + + assert.Equal([]int{}, DropRight([]int{}, 0)) + assert.Equal([]int{}, DropRight([]int{}, 1)) + assert.Equal([]int{}, DropRight([]int{}, -1)) + + assert.Equal([]int{1, 2, 3, 4, 5}, DropRight([]int{1, 2, 3, 4, 5}, 0)) + assert.Equal([]int{1, 2, 3, 4}, DropRight([]int{1, 2, 3, 4, 5}, 1)) + assert.Equal([]int{}, DropRight([]int{1, 2, 3, 4, 5}, 5)) + assert.Equal([]int{}, DropRight([]int{1, 2, 3, 4, 5}, 6)) + + assert.Equal([]int{1, 2, 3, 4, 5}, DropRight([]int{1, 2, 3, 4, 5}, -1)) } func TestInsertAt(t *testing.T) {