mirror of
https://github.com/samber/lo.git
synced 2025-09-26 20:11:13 +08:00
Added DropByIndex helper for slice (#398)
* added DropByIndex helper --------- Co-authored-by: Samuel Berthe <dev@samuel-berthe.fr>
This commit is contained in:
12
README.md
12
README.md
@@ -747,6 +747,18 @@ l := lo.DropRightWhile([]string{"a", "aa", "aaa", "aa", "aa"}, func(val string)
|
|||||||
|
|
||||||
[[play](https://go.dev/play/p/3-n71oEC0Hz)]
|
[[play](https://go.dev/play/p/3-n71oEC0Hz)]
|
||||||
|
|
||||||
|
### DropByIndex
|
||||||
|
|
||||||
|
Drops elements from a slice or array by the index. A negative index will drop elements from the end of the slice.
|
||||||
|
|
||||||
|
```go
|
||||||
|
l := lo.Drop([]int{0, 1, 2, 3, 4, 5}, 2, 4, -1)
|
||||||
|
// []int{2, 3}
|
||||||
|
```
|
||||||
|
|
||||||
|
[[play](https://go.dev/play/p/JswS7vXRJP2)]
|
||||||
|
|
||||||
|
|
||||||
### Reject
|
### Reject
|
||||||
|
|
||||||
The opposite of Filter, this method returns the elements of collection that predicate does not return truthy for.
|
The opposite of Filter, this method returns the elements of collection that predicate does not return truthy for.
|
||||||
|
33
slice.go
33
slice.go
@@ -1,6 +1,7 @@
|
|||||||
package lo
|
package lo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"sort"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
|
||||||
"github.com/samber/lo/internal/constraints"
|
"github.com/samber/lo/internal/constraints"
|
||||||
@@ -417,6 +418,38 @@ func DropRightWhile[T any, Slice ~[]T](collection Slice, predicate func(item T)
|
|||||||
return append(result, collection[:i+1]...)
|
return append(result, collection[:i+1]...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DropByIndex drops elements from a slice or array by the index.
|
||||||
|
// A negative index will drop elements from the end of the slice.
|
||||||
|
// Play: https://go.dev/play/p/bPIH4npZRxS
|
||||||
|
func DropByIndex[T any](collection []T, indexes ...int) []T {
|
||||||
|
initialSize := len(collection)
|
||||||
|
if initialSize == 0 {
|
||||||
|
return make([]T, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range indexes {
|
||||||
|
if indexes[i] < 0 {
|
||||||
|
indexes[i] = initialSize + indexes[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
indexes = Uniq(indexes)
|
||||||
|
sort.Ints(indexes)
|
||||||
|
|
||||||
|
result := make([]T, 0, initialSize)
|
||||||
|
result = append(result, collection...)
|
||||||
|
|
||||||
|
for i := range indexes {
|
||||||
|
if indexes[i]-i < 0 || indexes[i]-i >= initialSize-i {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
result = append(result[:indexes[i]-i], result[indexes[i]-i+1:]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
// Reject is the opposite of Filter, this method returns the elements of collection that predicate does not return truthy for.
|
// Reject is the opposite of Filter, this method returns the elements of collection that predicate does not return truthy for.
|
||||||
// Play: https://go.dev/play/p/YkLMODy1WEL
|
// Play: https://go.dev/play/p/YkLMODy1WEL
|
||||||
func Reject[T any, Slice ~[]T](collection Slice, predicate func(item T, index int) bool) Slice {
|
func Reject[T any, Slice ~[]T](collection Slice, predicate func(item T, index int) bool) Slice {
|
||||||
|
@@ -151,6 +151,26 @@ func BenchmarkDropRightWhile(b *testing.B) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkDropByIndex(b *testing.B) {
|
||||||
|
for _, n := range lengths {
|
||||||
|
strs := genSliceString(n)
|
||||||
|
b.Run(fmt.Sprintf("strings_%d", n), func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = DropByIndex(strs, n/4)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, n := range lengths {
|
||||||
|
ints := genSliceInt(n)
|
||||||
|
b.Run(fmt.Sprintf("ints%d", n), func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = DropByIndex(ints, n/4)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkReplace(b *testing.B) {
|
func BenchmarkReplace(b *testing.B) {
|
||||||
lengths := []int{1_000, 10_000, 100_000}
|
lengths := []int{1_000, 10_000, 100_000}
|
||||||
for _, n := range lengths {
|
for _, n := range lengths {
|
||||||
|
@@ -296,6 +296,15 @@ func ExampleDropRightWhile() {
|
|||||||
// Output: [0 1 2]
|
// Output: [0 1 2]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExampleDropByIndex() {
|
||||||
|
list := []int{0, 1, 2, 3, 4, 5}
|
||||||
|
|
||||||
|
result := DropByIndex(list, 2)
|
||||||
|
|
||||||
|
fmt.Printf("%v", result)
|
||||||
|
// Output: [0 1 3 4 5]
|
||||||
|
}
|
||||||
|
|
||||||
func ExampleReject() {
|
func ExampleReject() {
|
||||||
list := []int{0, 1, 2, 3, 4, 5}
|
list := []int{0, 1, 2, 3, 4, 5}
|
||||||
|
|
||||||
|
@@ -571,6 +571,27 @@ func TestDropRightWhile(t *testing.T) {
|
|||||||
is.IsType(nonempty, allStrings, "type preserved")
|
is.IsType(nonempty, allStrings, "type preserved")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDropByIndex(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
is := assert.New(t)
|
||||||
|
|
||||||
|
is.Equal([]int{1, 2, 3, 4}, DropByIndex([]int{0, 1, 2, 3, 4}, 0))
|
||||||
|
is.Equal([]int{3, 4}, DropByIndex([]int{0, 1, 2, 3, 4}, 0, 1, 2))
|
||||||
|
is.Equal([]int{0, 4}, DropByIndex([]int{0, 1, 2, 3, 4}, -4, -2, -3))
|
||||||
|
is.Equal([]int{0, 2, 3, 4}, DropByIndex([]int{0, 1, 2, 3, 4}, -4, -4))
|
||||||
|
is.Equal([]int{2, 4}, DropByIndex([]int{0, 1, 2, 3, 4}, 3, 1, 0))
|
||||||
|
is.Equal([]int{0, 1, 3, 4}, DropByIndex([]int{0, 1, 2, 3, 4}, 2))
|
||||||
|
is.Equal([]int{0, 1, 2, 3}, DropByIndex([]int{0, 1, 2, 3, 4}, 4))
|
||||||
|
is.Equal([]int{0, 1, 2, 3, 4}, DropByIndex([]int{0, 1, 2, 3, 4}, 5))
|
||||||
|
is.Equal([]int{0, 1, 2, 3, 4}, DropByIndex([]int{0, 1, 2, 3, 4}, 100))
|
||||||
|
is.Equal([]int{0, 1, 2, 3}, DropByIndex([]int{0, 1, 2, 3, 4}, -1))
|
||||||
|
is.Equal([]int{}, DropByIndex([]int{}, 0, 1))
|
||||||
|
is.Equal([]int{}, DropByIndex([]int{42}, 0, 1))
|
||||||
|
is.Equal([]int{}, DropByIndex([]int{42}, 1, 0))
|
||||||
|
is.Equal([]int{}, DropByIndex([]int{}, 1))
|
||||||
|
is.Equal([]int{}, DropByIndex([]int{1}, 0))
|
||||||
|
}
|
||||||
|
|
||||||
func TestReject(t *testing.T) {
|
func TestReject(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
is := assert.New(t)
|
is := assert.New(t)
|
||||||
|
Reference in New Issue
Block a user