The new slices package in Go 1.21 provides many slice-related functions that can be used for any type of slice.
slices.BinarySearch
The definition is as follows:
func BinarySearch[S ~[]E, E cmp.Ordered](x S, target E) (int, bool)
Search for the target in the sorted slices (the slices must be sorted in increasing order). If found, return the location and true. If not found, return the location where the target should be found and false. A simple example is as follows:
package main
import (
"fmt"
"slices"
)
func main() {
names := []string{"Alice", "Bob", "Vera"}
n, found := slices.BinarySearch(names, "Vera")
fmt.Println("Vera:", n, found) // Vera: 2 true
n, found = slices.BinarySearch(names, "Bill")
fmt.Println("Bill:", n, found) // Bill: 1 false
}
slices.BinarySearchFunc
The definition is as follows:
func BinarySearchFunc[S ~[]E, E, T any](x S, target T, cmp func(E, T) int) (int, bool)
It works like slices.BinarySearch, except that it uses a custom comparison function. Slices must be sorted in increasing order, where "increasing" is defined by cmp. CMP should return 0 if the slice element matches the target, a negative number if the slice element precedes the target, and a positive number if the slice element follows the target. CMP must implement the same ordering as slices, such that if CMP (a, t) < 0 and CMP (b, t) >= 0, the sliced a must come before b.
package main
import (
"cmp"
"fmt"
"slices"
)
func main() {
type Person struct {
Name string
Age int
}
people := []Person{
{"Alice", 55},
{"Bob", 24},
{"Gopher", 13},
}
n, found := slices.BinarySearchFunc(people, Person{"Bob", 0}, func(a, b Person) int {
return cmp.Compare(a.Name, b.Name)
})
fmt.Println("Bob:", n, found) // Bob: 1 true
}
slices.Clip
The definition is as follows:
func Clip[S ~[]E, E any](s S) S
Removes unused capacity from the slice, returning s[:len(s):len(s)]. A simple example is as follows:
package main
import (
"fmt"
"slices"
)
func main() {
names := make([]string, 2, 5)
names = slices.Clip(names)
fmt.Printf("长度:%d,容量:%d", len(names), cap(names))
// 长度:2,容量:2
}
slices.Clone
The definition is as follows:
func Clone[S ~[]E, E any](s S) S
Returns a copy of the slice. Because the elements are copied using assignment, this is a shallow clone. Simple and practical methods are as follows:
package main
import (
"fmt"
"slices"
)
func main() {
names := []string{"路多辛的博客", "路多辛的所思所想"}
namesCopy := slices.Clone(names)
fmt.Println(namesCopy)
}
slices.Compact
The definition is as follows:
func Compact[S ~[]E, E comparable](s S) S
Turn consecutive elements into one, similar to the uniq command on Unix. Compact modifies the contents of the slice and returns the modified slice, possibly smaller in length. A simple example is as follows:
package main
import (
"fmt"
"slices"
)
func main() {
seq := []int{0, 1, 1, 2, 5, 5, 5, 8}
seq = slices.Compact(seq)
fmt.Println(seq) // [0 1 2 5 8]
}
slices.CompactFunc
The definition is as follows:
func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S
Similar to slices.Compact, except that a custom function is used to compare elements. If the elements run equal, CompactFunc retains the first element. A simple example is as follows:
package main
import (
"fmt"
"slices"
"strings"
)
func main() {
names := []string{"bob", "Bob", "alice", "Vera", "VERA"}
names = slices.CompactFunc(names, func(a, b string) bool {
return strings.ToLower(a) == strings.ToLower(b)
})
fmt.Println(names) // [bob alice Vera]
}
slices.Compare
The definition is as follows:
func Compare[S ~[]E, E cmp.Ordered](s1, s2 S) int
Use the cmp.Compare function to compare the elements of s1 and s2. Each pair of elements is compared sequentially until one element is not equal to the other. Returns the result for the first unmatched element. If two slices are equal before one of them ends, the shorter slice is considered smaller than the longer slice. If s1 == s2, the result is 0; if s1 < s2, the result is -1; if s1 > s2, the result is 1.
package main
import (
"fmt"
"slices"
)
func main() {
names := []string{"Alice", "Bob", "Vera"}
fmt.Println("Equal:", slices.Compare(names, []string{"Alice", "Bob", "Vera"}))
fmt.Println("V < X:", slices.Compare(names, []string{"Alice", "Bob", "Xena"}))
fmt.Println("V > C:", slices.Compare(names, []string{"Alice", "Bob", "Cat"}))
fmt.Println("3 > 2:", slices.Compare(names, []string{"Alice", "Bob"}))
}
The running results are as follows:
Equal: 0
V < X: -1
V > C: 1
3 > 2: 1
slices.CompareFunc
The definition is as follows:
func CompareFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, cmp func(E1, E2) int) int
Similar to slices.Compare, except that a custom comparison function is used for comparison. The result is the first non-zero result of cmp; if cmp always returns 0, the result is 0 if len(s1) == len(s2), -1 if len(s1) < len(s2) len(s1) > len(s2) results in 1. A simple example is as follows:
package main
import (
"cmp"
"fmt"
"slices"
"strconv"
)
func main() {
numbers := []int{0, 43, 8}
strings := []string{"0", "0", "8"}
result := slices.CompareFunc(numbers, strings, func(n int, s string) int {
sn, err := strconv.Atoi(s)
if err != nil {
return 1
}
return cmp.Compare(n, sn)
})
fmt.Println(result) // 1
}
slices.Contains
The definition is as follows:
func Contains[S ~[]E, E comparable](s S, v E) bool
Used to determine whether s contains v. A simple example is as follows:
package main
import (
"fmt"
"slices"
)
func main() {
names := []string{"Alice", "Bob", "Vera"}
fmt.Println(slices.Contains(names, "Bob")) // true
}
slices.ContainsFunc
The definition is as follows:
func ContainsFunc[S ~[]E, E any](s S, f func(E) bool) bool
Used to determine whether at least one element e in s satisfies f(e). A simple example is as follows:
package main
import (
"fmt"
"slices"
)
func main() {
numbers := []int{0, 42, -10, 8}
hasNegative := slices.ContainsFunc(numbers, func(n int) bool {
return n < 0
})
fmt.Println("Has a negative:", hasNegative)// true
hasOdd := slices.ContainsFunc(numbers, func(n int) bool {
return n%2 != 0
})
fmt.Println("Has an odd number:", hasOdd) // false
}
【Reference】
Package slices(https://golang.google.cn/pkg/slices/)