From 9306682bccf6a68fe83ebbbb39a52721e60ea932 Mon Sep 17 00:00:00 2001 From: dsolerh Date: Thu, 18 Jul 2024 14:42:41 +0300 Subject: [PATCH 1/2] add PartitionIn2By implementation --- slice.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/slice.go b/slice.go index 431aaf04..5b8d817f 100644 --- a/slice.go +++ b/slice.go @@ -226,6 +226,26 @@ func PartitionBy[T any, K comparable, Slice ~[]T](collection Slice, iteratee fun // return Values[K, []T](groups) } +// PartitionIn2By returns two array of elements. The first returned array always contains the elements of +// the collection for which the iteratee function returned true, and the second the rest. This function is +// similar to PartitionBy, but guarantees that the output is going to contain two groups, though one may be +// with no elements. This is useful because removes the need to check if more than one group was returned, and +// also guarantees the order of the returned groups. +func PartitionIn2By[T any, Slice ~[]T](collection Slice, iteratee func(item T) bool) (Slice, Slice) { + trueSlice := Slice{} + falseSlice := Slice{} + + for _, item := range collection { + if iteratee(item) { + trueSlice = append(trueSlice, item) + } else { + falseSlice = append(falseSlice, item) + } + } + + return trueSlice, falseSlice +} + // Flatten returns an array a single level deep. // Play: https://go.dev/play/p/rbp9ORaMpjw func Flatten[T any, Slice ~[]T](collection []Slice) Slice { From 664ed38f72a89cf7d2405f193efe192cc974d0eb Mon Sep 17 00:00:00 2001 From: dsolerh Date: Thu, 18 Jul 2024 14:42:42 +0300 Subject: [PATCH 2/2] add example and test code --- slice_example_test.go | 12 ++++++++++++ slice_test.go | 20 ++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/slice_example_test.go b/slice_example_test.go index 0d64d8f0..d77244cf 100644 --- a/slice_example_test.go +++ b/slice_example_test.go @@ -183,6 +183,18 @@ func ExamplePartitionBy() { // [1 3] } +func ExamplePartitionIn2By() { + list := []int{-2, -1, 0, 1, 2} + + negative, positive := PartitionIn2By(list, func(x int) bool { return x < 0 }) + + fmt.Printf("%v\n", negative) + fmt.Printf("%v\n", positive) + // Output: + // [-2 -1] + // [0 1 2] +} + func ExampleFlatten() { list := [][]int{{0, 1, 2}, {3, 4, 5}} diff --git a/slice_test.go b/slice_test.go index abb9450e..28bc400f 100644 --- a/slice_test.go +++ b/slice_test.go @@ -292,6 +292,26 @@ func TestPartitionBy(t *testing.T) { }) is.IsType(nonempty[0], allStrings, "type preserved") } +func TestPartitionIn2By(t *testing.T) { + t.Parallel() + is := assert.New(t) + + isNegative := func(x int) bool { return x < 0 } + + negative1, positive1 := PartitionIn2By([]int{-2, -1, 0, 1, 2}, isNegative) + negative2, positive2 := PartitionIn2By([]int{}, isNegative) + + is.Equal(negative1, []int{-2, -1}) + is.Equal(positive1, []int{0, 1, 2}) + + is.Equal(negative2, []int{}) + is.Equal(positive2, []int{}) + + type myStrings []string + allStrings := myStrings{"", "foo", "bar"} + nonempty, _ := PartitionIn2By(allStrings, func(item string) bool { return len(item) != 0 }) + is.IsType(nonempty, allStrings, "type preserved") +} func TestFlatten(t *testing.T) { t.Parallel()