Open
Description
Proposal Details
In some scenarios, we need to divide the slice into two sub-slices that match and do not match by predicate, so it is proposed to provide the Partition
and PartitionInPlace
function.
Here are implementations
Partition
: Alloc new slice, and keep order, don't modify the original slice.
// 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) (S, S) {
if s == nil {
return nil, nil
}
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
}
PartitionInPlace
: No alloc slice, also not keep order, modify original slice.
func PartitionInPlace[E any, S ~[]E](s S, f func(E) bool) (true, false S) {
if s == nil {
return nil, nil
}
i, t := 0, len(s)-1
for i < t {
if !f(s[i]) {
i++
continue
}
s[i], s[t] = s[t], s[i]
t--
}
return s[:i], s[t:]
}
Usecases
Here is a simple search in github:
https://github.com/search?q=%2Ffunc%5Cs*%28%28P%7Cp%29artition%7C%28S%7Cs%29plit%29.*func%5C%28.*%5C%29+bool%5C%29%5Cs*%5C%28%2F+language%3AGo+++NOT+is%3Aarchived+NOT+is%3Afork+&type=code
It may not be an exact match, but it is enough to prove that the usage scenarios of partition are rich enough.
Also includes the following situations, which cannot be quickly retrieved by github search:
- There should be other function names that do similar things
- There are forms that do similar things directly instead of defining functions
Some specific examples:
Line 114 in 07fc591
- https://github.com/jesseduffield/lazygit/blob/618fe533f8c6113392eea981d03c65e6da5860bb/pkg/utils/slice.go#L131
- https://github.com/telepresenceio/telepresence/blob/1d0e76afabb392079ad2397e30eeb31b3a0fccd8/pkg/subnet/subnet.go#L131
- https://github.com/database64128/tfo-go/blob/3f17e86cda66000ab80dec80ef780db99c51509d/tfo_supported.go#L347
- https://github.com/felix-kaestner/slices/blob/9b6acd0396d156fe509b8a228820530ce03cd1e1/slices.go#L200
Metadata
Metadata
Assignees
Type
Projects
Status
Incoming