diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 934666a..cb39e01 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -17,7 +17,6 @@ jobs: - name: golangci-lint uses: golangci/golangci-lint-action@v8 with: - version: 'v2.4' args: --timeout 120s --max-same-issues 50 - name: Bearer diff --git a/errors.go b/errors.go index 4135736..135230a 100644 --- a/errors.go +++ b/errors.go @@ -129,7 +129,7 @@ func Try(callback func() error) (ok bool) { ok = false } - return + return ok } // Try0 has the same behavior as Try, but callback returns no variable. @@ -327,7 +327,7 @@ func TryWithErrorValue(callback func() error) (errorValue any, ok bool) { errorValue = err } - return + return errorValue, ok } // TryCatch has the same behavior as Try, but calls the catch function in case of error. diff --git a/slice.go b/slice.go index 9bca379..2be7dd9 100644 --- a/slice.go +++ b/slice.go @@ -113,7 +113,7 @@ func ForEach[T any](collection []T, iteratee func(item T, index int)) { // ForEachWhile iterates over elements of collection and invokes iteratee for each element // collection return value decide to continue or break, like do while(). // Play: https://go.dev/play/p/QnLGt35tnow -func ForEachWhile[T any](collection []T, iteratee func(item T, index int) (goon bool)) { +func ForEachWhile[T any](collection []T, iteratee func(item T, index int) bool) { for i := range collection { if !iteratee(collection[i], i) { break @@ -571,7 +571,9 @@ func FilterReject[T any, Slice ~[]T](collection Slice, predicate func(T, int) bo // Count counts the number of elements in the collection that equal value. // Play: https://go.dev/play/p/Y3FlK54yveC -func Count[T comparable](collection []T, value T) (count int) { +func Count[T comparable](collection []T, value T) int { + var count int + for i := range collection { if collection[i] == value { count++ @@ -583,7 +585,9 @@ func Count[T comparable](collection []T, value T) (count int) { // CountBy counts the number of elements in the collection for which predicate is true. // Play: https://go.dev/play/p/ByQbNYQQi4X -func CountBy[T any](collection []T, predicate func(item T) bool) (count int) { +func CountBy[T any](collection []T, predicate func(item T) bool) int { + var count int + for i := range collection { if predicate(collection[i]) { count++ diff --git a/slice_test.go b/slice_test.go index 5535db3..f84ea9d 100644 --- a/slice_test.go +++ b/slice_test.go @@ -1133,36 +1133,43 @@ func TestSplice(t *testing.T) { func TestCutSuccess(t *testing.T) { t.Parallel() is := assert.New(t) + // case 1 actualLeft, actualRight, result := Cut([]string{"a", "b", "c", "d", "e", "f", "g"}, []string{"a", "b"}) is.True(result) is.Equal([]string{}, actualLeft) is.Equal([]string{"c", "d", "e", "f", "g"}, actualRight) + // case 2 actualLeft, actualRight, result = Cut([]string{"a", "b", "c", "d", "e", "f", "g"}, []string{"f", "g"}) is.True(result) is.Equal([]string{"a", "b", "c", "d", "e"}, actualLeft) is.Equal([]string{}, actualRight) + // case 3 actualLeft, actualRight, result = Cut([]string{"g"}, []string{"g"}) is.True(result) is.Equal([]string{}, actualLeft) is.Equal([]string{}, actualRight) + // case 4 actualLeft, actualRight, result = Cut([]string{"a", "b", "c", "d", "e", "f", "g"}, []string{"b", "c"}) is.True(result) is.Equal([]string{"a"}, actualLeft) is.Equal([]string{"d", "e", "f", "g"}, actualRight) + // case 5 actualLeft, actualRight, result = Cut([]string{"a", "b", "c", "d", "e", "f", "g"}, []string{"e", "f"}) is.True(result) is.Equal([]string{"a", "b", "c", "d"}, actualLeft) is.Equal([]string{"g"}, actualRight) + // case 6 actualLeft, actualRight, result = Cut([]string{"a", "b"}, []string{"b"}) is.True(result) is.Equal([]string{"a"}, actualLeft) is.Equal([]string{}, actualRight) + // case 7 actualLeft, actualRight, result = Cut([]string{"a", "b"}, []string{"a"}) is.True(result) @@ -1173,16 +1180,19 @@ func TestCutSuccess(t *testing.T) { func TestCutFail(t *testing.T) { t.Parallel() is := assert.New(t) + // case 1 actualLeft, actualRight, result := Cut([]string{"a", "b", "c", "d", "e", "f", "g"}, []string{"z"}) is.False(result) is.Equal([]string{"a", "b", "c", "d", "e", "f", "g"}, actualLeft) is.Equal([]string{}, actualRight) + // case 2 actualLeft, actualRight, result = Cut([]string{}, []string{"z"}) is.False(result) is.Equal([]string{}, actualLeft) is.Equal([]string{}, actualRight) + // case 3 actualLeft, actualRight, result = Cut([]string{"a"}, []string{"z"}) is.False(result) @@ -1198,6 +1208,7 @@ type TestCutStruct struct { func TestCutPrefix(t *testing.T) { t.Parallel() is := assert.New(t) + // case 1 actualAfter, result := CutPrefix( []TestCutStruct{{id: 1, data: "a"}, {id: 2, data: "a"}, {id: 2, data: "b"}}, @@ -1205,6 +1216,7 @@ func TestCutPrefix(t *testing.T) { ) is.True(result) is.Equal([]TestCutStruct{{id: 2, data: "a"}, {id: 2, data: "b"}}, actualAfter) + // case 2 actualAfter, result = CutPrefix( []TestCutStruct{{id: 1, data: "a"}, {id: 2, data: "a"}, {id: 2, data: "b"}}, @@ -1212,6 +1224,7 @@ func TestCutPrefix(t *testing.T) { ) is.True(result) is.Equal([]TestCutStruct{{id: 1, data: "a"}, {id: 2, data: "a"}, {id: 2, data: "b"}}, actualAfter) + // case 3 actualAfter, result = CutPrefix( []TestCutStruct{{id: 1, data: "a"}, {id: 2, data: "a"}, {id: 2, data: "b"}}, @@ -1219,6 +1232,7 @@ func TestCutPrefix(t *testing.T) { ) is.False(result) is.Equal([]TestCutStruct{{id: 1, data: "a"}, {id: 2, data: "a"}, {id: 2, data: "b"}}, actualAfter) + // case 4 actualAfter, result = CutPrefix( []TestCutStruct{}, @@ -1226,6 +1240,7 @@ func TestCutPrefix(t *testing.T) { ) is.False(result) is.Equal([]TestCutStruct{}, actualAfter) + // case 5 actualAfterS, result := CutPrefix([]string{"a", "a", "b"}, []string{}) is.True(result) @@ -1235,6 +1250,7 @@ func TestCutPrefix(t *testing.T) { func TestCutSuffix(t *testing.T) { t.Parallel() is := assert.New(t) + // case 1 actualBefore, result := CutSuffix( []TestCutStruct{{id: 1, data: "a"}, {id: 2, data: "a"}, {id: 2, data: "b"}}, @@ -1242,6 +1258,7 @@ func TestCutSuffix(t *testing.T) { ) is.False(result) is.Equal([]TestCutStruct{{id: 1, data: "a"}, {id: 2, data: "a"}, {id: 2, data: "b"}}, actualBefore) + // case 2 actualBefore, result = CutSuffix( []TestCutStruct{{id: 1, data: "a"}, {id: 2, data: "a"}, {id: 2, data: "b"}}, @@ -1249,6 +1266,7 @@ func TestCutSuffix(t *testing.T) { ) is.True(result) is.Equal([]TestCutStruct{{id: 1, data: "a"}, {id: 2, data: "a"}}, actualBefore) + // case 3 actualBefore, result = CutSuffix( []TestCutStruct{{id: 1, data: "a"}, {id: 2, data: "a"}, {id: 2, data: "b"}}, @@ -1256,6 +1274,7 @@ func TestCutSuffix(t *testing.T) { ) is.True(result) is.Equal([]TestCutStruct{{id: 1, data: "a"}, {id: 2, data: "a"}, {id: 2, data: "b"}}, actualBefore) + // case 4 actualBefore, result = CutSuffix( []TestCutStruct{{id: 1, data: "a"}, {id: 2, data: "a"}, {id: 2, data: "b"}}, @@ -1263,6 +1282,7 @@ func TestCutSuffix(t *testing.T) { ) is.False(result) is.Equal([]TestCutStruct{{id: 1, data: "a"}, {id: 2, data: "a"}, {id: 2, data: "b"}}, actualBefore) + // case 5 actualAfterS, result := CutSuffix([]string{"a", "a", "b"}, []string{}) is.True(result) diff --git a/tuples_test.go b/tuples_test.go index 2933c1b..fdd92f3 100644 --- a/tuples_test.go +++ b/tuples_test.go @@ -506,7 +506,7 @@ func TestUnzipBy(t *testing.T) { t.Parallel() is := assert.New(t) - r1, r2 := UnzipBy2([]Tuple2[string, int]{{A: "a", B: 1}, {A: "b", B: 2}}, func(i Tuple2[string, int]) (a string, b int) { + r1, r2 := UnzipBy2([]Tuple2[string, int]{{A: "a", B: 1}, {A: "b", B: 2}}, func(i Tuple2[string, int]) (string, int) { return i.A + i.A, i.B + i.B }) diff --git a/type_manipulation.go b/type_manipulation.go index 3c00c6c..7738ec6 100644 --- a/type_manipulation.go +++ b/type_manipulation.go @@ -115,11 +115,12 @@ func FromAnySlice[T any](in []any) (out []T, ok bool) { } }() - result := make([]T, len(in)) + out = make([]T, len(in)) + ok = true for i := range in { - result[i] = in[i].(T) //nolint:errcheck,forcetypeassert + out[i] = in[i].(T) //nolint:errcheck,forcetypeassert } - return result, true + return out, ok } // Empty returns the zero value (https://go.dev/ref/spec#The_zero_value). @@ -145,16 +146,16 @@ func IsNotEmpty[T comparable](v T) bool { // Coalesce returns the first non-empty arguments. Arguments must be comparable. // Play: https://go.dev/play/p/Gyo9otyvFHH -func Coalesce[T comparable](values ...T) (result T, ok bool) { +func Coalesce[T comparable](values ...T) (T, bool) { + var zero T + for i := range values { - if values[i] != result { - result = values[i] - ok = true - return + if values[i] != zero { + return values[i], true } } - return + return zero, false } // CoalesceOrEmpty returns the first non-empty arguments. Arguments must be comparable.