Skip to content

Commit c86e720

Browse files
committed
slices: add Partition
Partition split the original slice into two slice. Fixes #67326.
1 parent 9623a35 commit c86e720

File tree

5 files changed

+65
-0
lines changed

5 files changed

+65
-0
lines changed

api/next/67326.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pkg slices, func Partition[$0 interface{ ~[]$1 }, $1 interface{}]($0, func($1) bool) ([]$1, []$1) #67326
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
The [Partition] function split original slice into two sub-slices
2+
by given predicate.
3+
The elements in the first slice all satisfy the predicate.
4+
The elements of the second slice none satisfy the predicate.

src/slices/example_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,3 +411,13 @@ func ExampleChunk() {
411411
// [{Bob 5} {Vera 24}]
412412
// [{Zac 15}]
413413
}
414+
415+
func ExamplePartition() {
416+
truthSlice, falseSlice := Partition([]int{1, 2, 3, 4, 5, 6}, func(x int) bool { return x%2 == 0 })
417+
fmt.Println(truthSlice)
418+
fmt.Println(falseSlice)
419+
420+
// Output:
421+
// [2 4 6]
422+
// [1 3 5]
423+
}

src/slices/slices.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,3 +506,19 @@ func Repeat[S ~[]E, E any](x S, count int) S {
506506
}
507507
return newslice
508508
}
509+
510+
// Partition split the original slice into two slice.
511+
// The elements of the first slice all satisfy the predicate.
512+
// The elements of the second slice none satisfy the predicate.
513+
func Partition[Slice ~[]E, E any](s Slice, f func(E) bool) ([]E, []E) {
514+
truthSlice := make([]E, 0)
515+
falseSlice := make([]E, 0)
516+
for _, x := range s {
517+
if f(x) {
518+
truthSlice = append(truthSlice, x)
519+
} else {
520+
falseSlice = append(falseSlice, x)
521+
}
522+
}
523+
return truthSlice, falseSlice
524+
}

src/slices/slices_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,3 +1450,37 @@ func TestRepeatPanics(t *testing.T) {
14501450
}
14511451
}
14521452
}
1453+
1454+
func TestPartition(t *testing.T) {
1455+
tests := []struct {
1456+
name string
1457+
original []int
1458+
truthSlice []int
1459+
falseSlice []int
1460+
predicate func(int) bool
1461+
}{
1462+
{
1463+
name: "split odd & even",
1464+
original: []int{1, 2, 3, 4, 5, 6},
1465+
truthSlice: []int{1, 3, 5},
1466+
falseSlice: []int{2, 4, 6},
1467+
predicate: func(x int) bool { return x%2 == 1 },
1468+
},
1469+
{
1470+
name: "split by pivot",
1471+
original: []int{1, 10, 100, 1000, 10000},
1472+
truthSlice: []int{1, 10},
1473+
falseSlice: []int{100, 1000, 10000},
1474+
predicate: func(x int) bool { return x < 100 },
1475+
},
1476+
}
1477+
for _, testCase := range tests {
1478+
truthSlice, falseSlice := Partition(testCase.original, testCase.predicate)
1479+
if !Equal(truthSlice, testCase.truthSlice) {
1480+
t.Errorf("Partition %s truth failed", testCase.name)
1481+
}
1482+
if !Equal(falseSlice, testCase.falseSlice) {
1483+
t.Errorf("Parition %s false failed", testCase.name)
1484+
}
1485+
}
1486+
}

0 commit comments

Comments
 (0)