Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions api/next/67326.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pkg slices, func Partition[$0 interface{ ~[]$1 }, $1 interface{}]($0, func($1) bool) ([]$1, []$1) #67326
4 changes: 4 additions & 0 deletions doc/next/6-stdlib/99-minor/slices/67326.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
The [Partition] function split original slice into two sub-slices
by given predicate.
The elements in the first slice all satisfy the predicate.
The elements of the second slice none satisfy the predicate.
10 changes: 10 additions & 0 deletions src/slices/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -411,3 +411,13 @@ func ExampleChunk() {
// [{Bob 5} {Vera 24}]
// [{Zac 15}]
}

func ExamplePartition() {
truthSlice, falseSlice := Partition([]int{1, 2, 3, 4, 5, 6}, func(x int) bool { return x%2 == 0 })
fmt.Println(truthSlice)
fmt.Println(falseSlice)

// Output:
// [2 4 6]
// [1 3 5]
}
16 changes: 16 additions & 0 deletions src/slices/slices.go
Original file line number Diff line number Diff line change
Expand Up @@ -506,3 +506,19 @@ func Repeat[S ~[]E, E any](x S, count int) S {
}
return newslice
}

// Partition split the original slice into two slice.
// The elements of the first slice all satisfy the predicate.
// The elements of the second slice none satisfy the predicate.
func Partition[Slice ~[]E, E any](s Slice, f func(E) bool) ([]E, []E) {
truthSlice := make([]E, 0)
falseSlice := make([]E, 0)
for _, x := range s {
if f(x) {
truthSlice = append(truthSlice, x)
} else {
falseSlice = append(falseSlice, x)
}
}
return truthSlice, falseSlice
}
34 changes: 34 additions & 0 deletions src/slices/slices_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1450,3 +1450,37 @@ func TestRepeatPanics(t *testing.T) {
}
}
}

func TestPartition(t *testing.T) {
tests := []struct {
name string
original []int
truthSlice []int
falseSlice []int
predicate func(int) bool
}{
{
name: "split odd & even",
original: []int{1, 2, 3, 4, 5, 6},
truthSlice: []int{1, 3, 5},
falseSlice: []int{2, 4, 6},
predicate: func(x int) bool { return x%2 == 1 },
},
{
name: "split by pivot",
original: []int{1, 10, 100, 1000, 10000},
truthSlice: []int{1, 10},
falseSlice: []int{100, 1000, 10000},
predicate: func(x int) bool { return x < 100 },
},
}
for _, testCase := range tests {
truthSlice, falseSlice := Partition(testCase.original, testCase.predicate)
if !Equal(truthSlice, testCase.truthSlice) {
t.Errorf("Partition %s truth failed", testCase.name)
}
if !Equal(falseSlice, testCase.falseSlice) {
t.Errorf("Parition %s false failed", testCase.name)
}
}
}