Generic functions for searching, sorting, comparing, and transforming slices of any type, replacing the hand-written loops and sort.Interface boilerplate Go needed before generics.
Examples
Contains and Index do a linear scan. BinarySearch needs a sorted slice but runs in O(log n) instead of O(n).
nums := []int{4, 8, 15, 16, 23, 42}
fmt.Println(slices.Contains(nums, 15))
fmt.Println(slices.Index(nums, 16))
i, found := slices.BinarySearch(nums, 23)
fmt.Println(i, found)true
3
4 trueSort works on any ordered element type with no comparison function. SortFunc takes over once you need a custom order, like sorting a struct by one field.
type player struct {
Name string
Score int
}
nums := []int{5, 2, 9, 1}
slices.Sort(nums)
fmt.Println(nums, slices.IsSorted(nums))
players := []player{{"Ada", 40}, {"Lin", 90}, {"Max", 15}}
slices.SortFunc(players, func(a, b player) int {
return cmp.Compare(b.Score, a.Score)
})
fmt.Println(players)[1 2 5 9] true
[{Lin 90} {Ada 40} {Max 15}]Compact, Insert, Delete, and Reverse all edit a slice's contents in place and return the (possibly re-sliced) result — always reassign the return value.
nums := []int{1, 1, 2, 2, 2, 3}
nums = slices.Compact(nums)
fmt.Println(nums)
nums = slices.Insert(nums, 1, 10, 20)
fmt.Println(nums)
nums = slices.Delete(nums, 1, 3)
fmt.Println(nums)
slices.Reverse(nums)
fmt.Println(nums)[1 2 3]
[1 10 20 2 3]
[1 2 3]
[3 2 1]Equal and Compare check whole slices at once. Max and Min scan for an extreme value directly, no manual loop needed.
a := []int{1, 2, 3}
b := []int{1, 2, 3}
fmt.Println(slices.Equal(a, b))
prices := []float64{9.99, 4.50, 19.75, 2.00}
fmt.Println(slices.Max(prices), slices.Min(prices))
fmt.Println(slices.Compare([]int{1, 2}, []int{1, 3}))true
19.75 2
-1Clone copies a slice to a new backing array, so edits to the copy never touch the original. Concat and Grow both allocate room up front instead of growing one append at a time.
original := []int{1, 2, 3}
clone := slices.Clone(original)
clone[0] = 99
fmt.Println(original, clone)
merged := slices.Concat([]int{1, 2}, []int{3, 4}, []int{5})
fmt.Println(merged)
grown := slices.Grow(merged, 10)
fmt.Println(len(grown), cap(grown) >= 15)[1 2 3] [99 2 3]
[1 2 3 4 5]
5 trueAll and Values (Go 1.23+) turn a slice into a range-over-func iterator, which composes with the rest of the package — Sorted collects and sorts one in a single call.
names := []string{"beta", "alpha", "gamma"}
for i, n := range slices.All(names) {
fmt.Println(i, n)
}
sorted := slices.Sorted(slices.Values(names))
fmt.Println(sorted)0 beta
1 alpha
2 gamma
[alpha beta gamma]| Function | Description |
|---|---|
All(s) iter.Seq2[int, E] | Returns an iterator over index-value pairs of s, the range-over-func form of a plain for loop. |
AppendSeq(s, seq) []E | Appends every value from seq onto s. |
Backward(s) iter.Seq2[int, E] | Like All, but iterates from the last element to the first. |
Chunk(s, n) iter.Seq[[]E] | Iterates over consecutive sub-slices of up to n elements each. |
Collect(seq) []E Collect(Values(s)) | Collects every value from an iterator into a new slice. |
Sorted(seq) []E Sorted(Values(s)) | Collects seq into a slice and sorts it in one step. |
SortedFunc(seq, cmp) []E | Like Sorted, using a custom comparison function. |
SortedStableFunc(seq, cmp) []E | Like SortedFunc, but preserves the original order of equal elements. |
Values(s) iter.Seq[E] | Returns an iterator over the elements of s, without their indices. |
BinarySearch(x, target) (int, bool) BinarySearch([]int{1,3,5}, 3) // 1, true | Searches a sorted slice for target, returning the insertion index and whether it was found. |
BinarySearchFunc(x, target, cmp) (int, bool) | Like BinarySearch, using a custom comparison function. |
Contains(s, v) bool Contains([]int{1,2,3}, 2) // true | Reports whether v appears in s. |
ContainsFunc(s, f) bool | Reports whether any element of s satisfies f. |
Index(s, v) int Index([]int{4,8,15}, 8) // 1 | Returns the index of v's first occurrence in s, or -1. |
IndexFunc(s, f) int | Returns the index of the first element satisfying f, or -1. |
IsSorted(x) bool | Reports whether x is sorted in ascending order. |
IsSortedFunc(x, cmp) bool | Like IsSorted, using a custom comparison function. |
Max(x) E Max([]int{3,1,4}) // 4 | Returns the largest element of x. Panics if x is empty. |
MaxFunc(x, cmp) E | Like Max, using a custom comparison function. |
Min(x) E Min([]int{3,1,4}) // 1 | Returns the smallest element of x. Panics if x is empty. |
MinFunc(x, cmp) E | Like Min, using a custom comparison function. |
Reverse(s) | Reverses the elements of s in place. |
Sort(x) Sort(nums) | Sorts x in ascending order in place. |
SortFunc(x, cmp) | Sorts x in place using a custom comparison function. |
SortStableFunc(x, cmp) | Like SortFunc, but preserves the original order of equal elements. |
Compare(s1, s2) int | Lexicographically compares two slices, returning -1, 0, or 1. |
CompareFunc(s1, s2, cmp) int | Like Compare, using a custom comparison function. |
Equal(s1, s2) bool Equal([]int{1,2}, []int{1,2}) // true | Reports whether two slices have the same length and equal elements. |
EqualFunc(s1, s2, eq) bool | Like Equal, using a custom equality function. |
Clip(s) []E | Removes unused capacity from s, so len(s) == cap(s). |
Clone(s) []E Clone(s) | Returns a copy of s backed by a new array. |
Compact(s) []E Compact([]int{1,1,2}) // [1 2] | Replaces consecutive runs of equal elements with a single copy, like the Unix uniq command. |
CompactFunc(s, eq) []E | Like Compact, using a custom equality function. |
Concat(slices...) []E | Concatenates multiple slices into one new slice. |
Delete(s, i, j) []E | Removes s[i:j], shifting later elements left. |
DeleteFunc(s, del) []E | Removes every element for which del returns true. |
Grow(s, n) []E | Extends s's capacity by at least n elements without changing its length. |
Insert(s, i, v...) []E | Inserts values before index i, shifting later elements right. |
Repeat(x, count) []E | Returns a new slice with the elements of x repeated count times. |
Replace(s, i, j, v...) []E | Replaces s[i:j] with v, which may have a different length than the removed range. |
Most functions here take and return a plain slice of any element type, using generics instead of the old sort.Interface pattern. Functions ending in Func take a custom comparison or equality callback for element types that aren't directly ordered or comparable.