aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/maps/example_test.go45
-rw-r--r--src/slices/example_test.go322
-rw-r--r--src/slices/slices.go11
-rw-r--r--src/slices/sort.go4
4 files changed, 374 insertions, 8 deletions
diff --git a/src/maps/example_test.go b/src/maps/example_test.go
new file mode 100644
index 0000000000..779c66dcef
--- /dev/null
+++ b/src/maps/example_test.go
@@ -0,0 +1,45 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package maps_test
+
+import (
+ "fmt"
+ "maps"
+ "strings"
+)
+
+func ExampleDeleteFunc() {
+ m := map[string]int{
+ "one": 1,
+ "two": 2,
+ "three": 3,
+ "four": 4,
+ }
+ maps.DeleteFunc(m, func(k string, v int) bool {
+ return v%2 != 0 // delete odd values
+ })
+ fmt.Println(m)
+ // Output:
+ // map[four:4 two:2]
+}
+
+func ExampleEqualFunc() {
+ m1 := map[int]string{
+ 1: "one",
+ 10: "Ten",
+ 1000: "THOUSAND",
+ }
+ m2 := map[int][]byte{
+ 1: []byte("One"),
+ 10: []byte("Ten"),
+ 1000: []byte("Thousand"),
+ }
+ eq := maps.EqualFunc(m1, m2, func(v1 string, v2 []byte) bool {
+ return strings.ToLower(v1) == strings.ToLower(string(v2))
+ })
+ fmt.Println(eq)
+ // Output:
+ // true
+}
diff --git a/src/slices/example_test.go b/src/slices/example_test.go
new file mode 100644
index 0000000000..3e76907bb7
--- /dev/null
+++ b/src/slices/example_test.go
@@ -0,0 +1,322 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package slices_test
+
+import (
+ "cmp"
+ "fmt"
+ "slices"
+ "strconv"
+ "strings"
+)
+
+func ExampleBinarySearch() {
+ names := []string{"Alice", "Bob", "Vera"}
+ n, found := slices.BinarySearch(names, "Vera")
+ fmt.Println("Vera:", n, found)
+ n, found = slices.BinarySearch(names, "Bill")
+ fmt.Println("Bill:", n, found)
+ // Output:
+ // Vera: 2 true
+ // Bill: 1 false
+}
+
+func ExampleBinarySearchFunc() {
+ 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)
+ // Output:
+ // Bob: 1 true
+}
+
+func ExampleCompact() {
+ seq := []int{0, 1, 1, 2, 3, 5, 8}
+ seq = slices.Compact(seq)
+ fmt.Println(seq)
+ // Output:
+ // [0 1 2 3 5 8]
+}
+
+func ExampleCompactFunc() {
+ 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)
+ // Output:
+ // [bob alice Vera]
+}
+
+func ExampleCompare() {
+ 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"}))
+ // Output:
+ // Equal: 0
+ // V < X: -1
+ // V > C: 1
+ // 3 > 2: 1
+}
+
+func ExampleCompareFunc() {
+ 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)
+ // Output:
+ // 1
+}
+
+func ExampleContainsFunc() {
+ numbers := []int{0, 42, -10, 8}
+ hasNegative := slices.ContainsFunc(numbers, func(n int) bool {
+ return n < 0
+ })
+ fmt.Println("Has a negative:", hasNegative)
+ hasOdd := slices.ContainsFunc(numbers, func(n int) bool {
+ return n%2 != 0
+ })
+ fmt.Println("Has an odd number:", hasOdd)
+ // Output:
+ // Has a negative: true
+ // Has an odd number: false
+}
+
+func ExampleDelete() {
+ letters := []string{"a", "b", "c", "d", "e"}
+ letters = slices.Delete(letters, 1, 4)
+ fmt.Println(letters)
+ // Output:
+ // [a e]
+}
+
+func ExampleDeleteFunc() {
+ seq := []int{0, 1, 1, 2, 3, 5, 8}
+ seq = slices.DeleteFunc(seq, func(n int) bool {
+ return n%2 != 0 // delete the odd numbers
+ })
+ fmt.Println(seq)
+ // Output:
+ // [0 2 8]
+}
+
+func ExampleEqual() {
+ numbers := []int{0, 42, 8}
+ fmt.Println(slices.Equal(numbers, []int{0, 42, 8}))
+ fmt.Println(slices.Equal(numbers, []int{10}))
+ // Output:
+ // true
+ // false
+}
+
+func ExampleEqualFunc() {
+ numbers := []int{0, 42, 8}
+ strings := []string{"000", "42", "0o10"}
+ equal := slices.EqualFunc(numbers, strings, func(n int, s string) bool {
+ sn, err := strconv.ParseInt(s, 0, 64)
+ if err != nil {
+ return false
+ }
+ return n == int(sn)
+ })
+ fmt.Println(equal)
+ // Output:
+ // true
+}
+
+func ExampleIndex() {
+ numbers := []int{0, 42, 8}
+ fmt.Println(slices.Index(numbers, 8))
+ fmt.Println(slices.Index(numbers, 7))
+ // Output:
+ // 2
+ // -1
+}
+
+func ExampleIndexFunc() {
+ numbers := []int{0, 42, -10, 8}
+ i := slices.IndexFunc(numbers, func(n int) bool {
+ return n < 0
+ })
+ fmt.Println("First negative at index", i)
+ // Output:
+ // First negative at index 2
+}
+
+func ExampleInsert() {
+ names := []string{"Alice", "Bob", "Vera"}
+ names = slices.Insert(names, 1, "Bill", "Billie")
+ names = slices.Insert(names, len(names), "Zac")
+ fmt.Println(names)
+ // Output:
+ // [Alice Bill Billie Bob Vera Zac]
+}
+
+func ExampleIsSorted() {
+ fmt.Println(slices.IsSorted([]string{"Alice", "Bob", "Vera"}))
+ fmt.Println(slices.IsSorted([]int{0, 2, 1}))
+ // Output:
+ // true
+ // false
+}
+
+func ExampleIsSortedFunc() {
+ names := []string{"alice", "Bob", "VERA"}
+ isSortedInsensitive := slices.IsSortedFunc(names, func(a, b string) int {
+ return cmp.Compare(strings.ToLower(a), strings.ToLower(b))
+ })
+ fmt.Println(isSortedInsensitive)
+ fmt.Println(slices.IsSorted(names))
+ // Output:
+ // true
+ // false
+}
+
+func ExampleMax() {
+ numbers := []int{0, 42, -10, 8}
+ fmt.Println(slices.Max(numbers))
+ // Output:
+ // 42
+}
+
+func ExampleMaxFunc() {
+ type Person struct {
+ Name string
+ Age int
+ }
+ people := []Person{
+ {"Gopher", 13},
+ {"Alice", 55},
+ {"Vera", 24},
+ {"Bob", 55},
+ }
+ firstOldest := slices.MaxFunc(people, func(a, b Person) int {
+ return cmp.Compare(a.Age, b.Age)
+ })
+ fmt.Println(firstOldest.Name)
+ // Output:
+ // Alice
+}
+
+func ExampleMin() {
+ numbers := []int{0, 42, -10, 8}
+ fmt.Println(slices.Min(numbers))
+ // Output:
+ // -10
+}
+
+func ExampleMinFunc() {
+ type Person struct {
+ Name string
+ Age int
+ }
+ people := []Person{
+ {"Gopher", 13},
+ {"Bob", 5},
+ {"Vera", 24},
+ {"Bill", 5},
+ }
+ firstYoungest := slices.MinFunc(people, func(a, b Person) int {
+ return cmp.Compare(a.Age, b.Age)
+ })
+ fmt.Println(firstYoungest.Name)
+ // Output:
+ // Bob
+}
+
+func ExampleReplace() {
+ names := []string{"Alice", "Bob", "Vera", "Zac"}
+ names = slices.Replace(names, 1, 3, "Bill", "Billie", "Cat")
+ fmt.Println(names)
+ // Output:
+ // [Alice Bill Billie Cat Zac]
+}
+
+func ExampleReverse() {
+ names := []string{"alice", "Bob", "VERA"}
+ slices.Reverse(names)
+ fmt.Println(names)
+ // Output:
+ // [VERA Bob alice]
+}
+
+func ExampleSort() {
+ smallInts := []int8{0, 42, -10, 8}
+ slices.Sort(smallInts)
+ fmt.Println(smallInts)
+ // Output:
+ // [-10 0 8 42]
+}
+
+func ExampleSortFunc_caseInsensitive() {
+ names := []string{"Bob", "alice", "VERA"}
+ slices.SortFunc(names, func(a, b string) int {
+ return cmp.Compare(strings.ToLower(a), strings.ToLower(b))
+ })
+ fmt.Println(names)
+ // Output:
+ // [alice Bob VERA]
+}
+
+func ExampleSortFunc_multiField() {
+ type Person struct {
+ Name string
+ Age int
+ }
+ people := []Person{
+ {"Gopher", 13},
+ {"Alice", 55},
+ {"Bob", 24},
+ {"Alice", 20},
+ }
+ slices.SortFunc(people, func(a, b Person) int {
+ if n := cmp.Compare(a.Name, b.Name); n != 0 {
+ return n
+ }
+ // If names are equal, order by age
+ return cmp.Compare(a.Age, b.Age)
+ })
+ fmt.Println(people)
+ // Output:
+ // [{Alice 20} {Alice 55} {Bob 24} {Gopher 13}]
+}
+
+func ExampleSortStableFunc() {
+ type Person struct {
+ Name string
+ Age int
+ }
+ people := []Person{
+ {"Gopher", 13},
+ {"Alice", 20},
+ {"Bob", 24},
+ {"Alice", 55},
+ }
+ // Stable sort by name, keeping age ordering of Alices intact
+ slices.SortStableFunc(people, func(a, b Person) int {
+ return cmp.Compare(a.Name, b.Name)
+ })
+ fmt.Println(people)
+ // Output:
+ // [{Alice 20} {Alice 55} {Bob 24} {Gopher 13}]
+}
diff --git a/src/slices/slices.go b/src/slices/slices.go
index 653d4dd093..afeed0afb5 100644
--- a/src/slices/slices.go
+++ b/src/slices/slices.go
@@ -27,7 +27,7 @@ func Equal[S ~[]E, E comparable](s1, s2 S) bool {
return true
}
-// EqualFunc reports whether two slices are equal using a comparison
+// EqualFunc reports whether two slices are equal using an equality
// function on each pair of elements. If the lengths are different,
// EqualFunc returns false. Otherwise, the elements are compared in
// increasing index order, and the comparison stops at the first index
@@ -210,7 +210,6 @@ func Insert[S ~[]E, E any](s S, i int, v ...E) S {
// Delete removes the elements s[i:j] from s, returning the modified slice.
// Delete panics if s[i:j] is not a valid slice of s.
-// Delete modifies the contents of the slice s; it does not create a new slice.
// Delete is O(len(s)-j), so if many items must be deleted, it is better to
// make a single call deleting them all together than to delete one at a time.
// Delete might not modify the elements s[len(s)-(j-i):len(s)]. If those
@@ -224,8 +223,6 @@ func Delete[S ~[]E, E any](s S, i, j int) S {
// DeleteFunc removes any elements from s for which del returns true,
// returning the modified slice.
-// DeleteFunc modifies the contents of the slice s;
-// it does not create a new slice.
// When DeleteFunc removes m elements, it might not modify the elements
// s[len(s)-m:len(s)]. If those elements contain pointers you might consider
// zeroing those elements so that objects they reference can be garbage
@@ -348,7 +345,8 @@ func Clone[S ~[]E, E any](s S) S {
// Compact replaces consecutive runs of equal elements with a single copy.
// This is like the uniq command found on Unix.
-// Compact modifies the contents of the slice s; it does not create a new slice.
+// Compact modifies the contents of the slice s and returns the modified slice,
+// which may have a smaller length.
// When Compact discards m elements in total, it might not modify the elements
// s[len(s)-m:len(s)]. If those elements contain pointers you might consider
// zeroing those elements so that objects they reference can be garbage collected.
@@ -368,7 +366,8 @@ func Compact[S ~[]E, E comparable](s S) S {
return s[:i]
}
-// CompactFunc is like [Compact] but uses a comparison function.
+// CompactFunc is like [Compact] but uses an equality function to compare elements.
+// For runs of elements that compare equal, CompactFunc keeps the first one.
func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S {
if len(s) < 2 {
return s
diff --git a/src/slices/sort.go b/src/slices/sort.go
index a634c12f6f..822f2fceb4 100644
--- a/src/slices/sort.go
+++ b/src/slices/sort.go
@@ -29,7 +29,7 @@ func SortFunc[S ~[]E, E any](x S, cmp func(a, b E) int) {
}
// SortStableFunc sorts the slice x while keeping the original order of equal
-// elements, using cmp to compare elements.
+// elements, using cmp to compare elements in the same way as [SortFunc].
func SortStableFunc[S ~[]E, E any](x S, cmp func(a, b E) int) {
stableCmpFunc(x, len(x), cmp)
}
@@ -45,7 +45,7 @@ func IsSorted[S ~[]E, E cmp.Ordered](x S) bool {
}
// IsSortedFunc reports whether x is sorted in ascending order, with cmp as the
-// comparison function.
+// comparison function as defined by [SortFunc].
func IsSortedFunc[S ~[]E, E any](x S, cmp func(a, b E) int) bool {
for i := len(x) - 1; i > 0; i-- {
if cmp(x[i], x[i-1]) < 0 {