feat: preserve type alias in DropByIndex and WithoutBy (#675)

* lint: pin golangci-lint version

* feat: preserve type alias in WithoutBy

* feat: preserve type alias in DropByIndex

---------

Co-authored-by: Samuel Berthe <dev@samuel-berthe.fr>
This commit is contained in:
Nathan Baulch
2025-09-25 06:57:40 +10:00
committed by GitHub
parent 5196e100c3
commit 41cbf0fd2b
5 changed files with 19 additions and 6 deletions

View File

@@ -17,6 +17,7 @@ jobs:
- name: golangci-lint
uses: golangci/golangci-lint-action@v8
with:
version: 'v2.4'
args: --timeout 120s --max-same-issues 50
- name: Bearer

View File

@@ -196,13 +196,13 @@ func Without[T comparable, Slice ~[]T](collection Slice, exclude ...T) Slice {
// WithoutBy filters a slice by excluding elements whose extracted keys match any in the exclude list.
// Returns a new slice containing only the elements whose keys are not in the exclude list.
// Play: https://go.dev/play/p/VgWJOF01NbJ
func WithoutBy[T any, K comparable](collection []T, iteratee func(item T) K, exclude ...K) []T {
func WithoutBy[T any, K comparable, Slice ~[]T](collection Slice, iteratee func(item T) K, exclude ...K) Slice {
excludeMap := make(map[K]struct{}, len(exclude))
for _, e := range exclude {
excludeMap[e] = struct{}{}
}
result := make([]T, 0, len(collection))
result := make(Slice, 0, len(collection))
for _, item := range collection {
if _, ok := excludeMap[iteratee(item)]; !ok {
result = append(result, item)

View File

@@ -288,8 +288,15 @@ func TestWithoutBy(t *testing.T) {
result2 := WithoutBy([]User{}, func(item User) int { return item.Age }, 1, 2, 3)
result3 := WithoutBy([]User{}, func(item User) string { return item.Name })
is.Equal([]User{{Name: "peter"}}, result1)
is.Empty(result2)
is.Empty(result2)
is.Empty(result3)
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
nonempty := WithoutBy(allStrings, func(s string) string {
return s
})
is.IsType(nonempty, allStrings, "type preserved")
}
func TestWithoutEmpty(t *testing.T) {

View File

@@ -490,10 +490,10 @@ func DropRightWhile[T any, Slice ~[]T](collection Slice, predicate func(item T)
// DropByIndex drops elements from a slice 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 {
func DropByIndex[T any, Slice ~[]T](collection Slice, indexes ...int) Slice {
initialSize := len(collection)
if initialSize == 0 {
return make([]T, 0)
return make(Slice, 0)
}
for i := range indexes {
@@ -505,7 +505,7 @@ func DropByIndex[T any](collection []T, indexes ...int) []T {
indexes = Uniq(indexes)
sort.Ints(indexes)
result := make([]T, 0, initialSize)
result := make(Slice, 0, initialSize)
result = append(result, collection...)
for i := range indexes {

View File

@@ -716,6 +716,11 @@ func TestDropByIndex(t *testing.T) {
is.Empty(DropByIndex([]int{42}, 1, 0))
is.Empty(DropByIndex([]int{}, 1))
is.Empty(DropByIndex([]int{1}, 0))
type myStrings []string
allStrings := myStrings{"", "foo", "bar"}
nonempty := DropByIndex(allStrings, 0)
is.IsType(nonempty, allStrings, "type preserved")
}
func TestReject(t *testing.T) {