Documentation
¶
Overview ¶
Package sliceutil provides generic slice operations for Go.
All functions in this package work with any comparable or ordered type through Go's generics. The package avoids allocations where possible and provides both in-place and copying variants of mutating operations.
Design Principles ¶
- Generic: Works with any type that satisfies the constraints
- Non-mutating by default: Functions return new slices unless suffixed with "InPlace"
- Nil-safe: All functions handle nil slices gracefully
- Zero allocations: Where possible, operations avoid heap allocations
Basic Operations ¶
// Filter elements
evens := sliceutil.Filter([]int{1, 2, 3, 4}, func(n int) bool { return n%2 == 0 })
// Transform elements
doubled := sliceutil.Map([]int{1, 2, 3}, func(n int) int { return n * 2 })
// Check containment
if sliceutil.Contains(names, "Alice") { ... }
Chunking and Grouping ¶
// Split into chunks of size 3
chunks := sliceutil.Chunk(items, 3)
// Group items by key
groups := sliceutil.GroupBy([]string{"a", "bb"}, func(item string) int { return len(item) })
Set Operations ¶
unique := sliceutil.Unique(items) intersection := sliceutil.Intersect(a, b) difference := sliceutil.Difference(a, b)
Index ¶
- func All[T any](s []T, predicate func(T) bool) bool
- func Any[T any](s []T, predicate func(T) bool) bool
- func Associate[T any, K comparable](s []T, key func(T) K) map[K]T
- func AssociateWith[K comparable, V any](s []K, value func(K) V) map[K]V
- func Chunk[T any](s []T, size int) [][]T
- func Compact[T comparable](s []T) []T
- func CompactFunc[T any](s []T, eq func(T, T) bool) []T
- func Contains[T comparable](s []T, target T) bool
- func ContainsFunc[T any](s []T, predicate func(T) bool) bool
- func Count[T any](s []T, predicate func(T) bool) int
- func Difference[T comparable](a, b []T) []T
- func Drop[T any](s []T, n int) []T
- func DropLast[T any](s []T, n int) []T
- func DropWhile[T any](s []T, predicate func(T) bool) []T
- func Equal[T comparable](a, b []T) bool
- func EqualFunc[T, U any](a []T, b []U, eq func(T, U) bool) bool
- func Filter[T any](s []T, predicate func(T) bool) []T
- func FilterInPlace[T any](s []T, predicate func(T) bool) []T
- func Find[T any](s []T, predicate func(T) bool) (T, bool)
- func FindLast[T any](s []T, predicate func(T) bool) (T, bool)
- func FlatMap[T, U any](s []T, transform func(T) []U) []U
- func Flatten[T any](s [][]T) []T
- func ForEach[T any](s []T, fn func(T))
- func ForEachWithIndex[T any](s []T, fn func(int, T))
- func GroupBy[T any, K comparable](s []T, key func(T) K) map[K][]T
- func IndexOf[T comparable](s []T, target T) int
- func IndexOfFunc[T any](s []T, predicate func(T) bool) int
- func Insert[T any](s []T, index int, value T) []T
- func Intersect[T comparable](a, b []T) []T
- func LastIndexOf[T comparable](s []T, target T) int
- func Map[T, U any](s []T, transform func(T) U) []U
- func MapErr[T, U any](s []T, fn func(T) (U, error)) ([]U, error)
- func MapWithIndex[T, U any](s []T, transform func(int, T) U) []U
- func Max[T cmp.Ordered](s []T) (T, bool)
- func MaxFunc[T any](s []T, cmpFn func(a, b T) int) (T, bool)
- func Min[T cmp.Ordered](s []T) (T, bool)
- func MinFunc[T any](s []T, cmpFn func(a, b T) int) (T, bool)
- func None[T any](s []T, predicate func(T) bool) bool
- func Pad[T any](s []T, length int, fill T) []T
- func PadLeft[T any](s []T, length int, fill T) []T
- func Partition[T any](s []T, predicate func(T) bool) (matching, notMatching []T)
- func Reduce[T, U any](s []T, initial U, accumulator func(U, T) U) U
- func RemoveAt[T any](s []T, index int) []T
- func RemoveFirst[T comparable](s []T, value T) []T
- func RemoveValue[T comparable](s []T, value T) []T
- func Reverse[T any](s []T) []T
- func ReverseInPlace[T any](s []T) []T
- func SeedShuffle(seed uint64)
- func Shuffle[T any](s []T) []T
- func ShuffleInPlace[T any](s []T)
- func Take[T any](s []T, n int) []T
- func TakeLast[T any](s []T, n int) []T
- func TakeWhile[T any](s []T, predicate func(T) bool) []T
- func Union[T comparable](a, b []T) []T
- func Unique[T comparable](s []T) []T
- func UniqueFunc[T any, K comparable](s []T, key func(T) K) []T
- func Zip[T, U any](a []T, b []U) [][2]any
- func ZipWith[T, U, V any](a []T, b []U, combine func(T, U) V) []V
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func All ¶
All returns true if all elements satisfy the predicate. Returns true for empty slices.
Example:
allPositive := All([]int{1, 2, 3}, func(n int) bool { return n > 0 })
// allPositive = true
func Any ¶
Any returns true if any element satisfies the predicate. Returns false for empty slices.
Example:
hasNegative := Any([]int{1, -2, 3}, func(n int) bool { return n < 0 })
// hasNegative = true
func Associate ¶
func Associate[T any, K comparable](s []T, key func(T) K) map[K]T
Associate creates a map from slice elements using a key function.
Example:
users := []User{{ID: 1, Name: "Alice"}, {ID: 2, Name: "Bob"}}
byID := Associate(users, func(u User) int { return u.ID })
// byID = map[1:{1, "Alice"} 2:{2, "Bob"}]
func AssociateWith ¶
func AssociateWith[K comparable, V any](s []K, value func(K) V) map[K]V
AssociateWith creates a map from slice elements to values computed by a function.
Example:
lengths := AssociateWith([]string{"a", "bb", "ccc"}, func(s string) int { return len(s) })
// lengths = map["a":1 "bb":2 "ccc":3]
func Chunk ¶
Chunk splits a slice into chunks of the specified size. The last chunk may be smaller if len(s) is not divisible by size. Returns nil if size <= 0 or s is nil.
Example:
chunks := Chunk([]int{1, 2, 3, 4, 5}, 2)
// chunks = [[1, 2], [3, 4], [5]]
func Compact ¶
func Compact[T comparable](s []T) []T
Compact removes consecutive duplicate elements, similar to Unix uniq. For removing all duplicates, use Unique.
Example:
compacted := Compact([]int{1, 1, 2, 2, 2, 1})
// compacted = [1, 2, 1]
func CompactFunc ¶
CompactFunc removes consecutive elements where the predicate returns true.
func Contains ¶
func Contains[T comparable](s []T, target T) bool
Contains reports whether the slice contains the target element. Uses == for comparison, requiring comparable types.
Example:
if Contains(names, "Alice") { ... }
func ContainsFunc ¶
ContainsFunc reports whether any element satisfies the predicate.
Example:
hasNegative := ContainsFunc(nums, func(n int) bool { return n < 0 })
func Difference ¶
func Difference[T comparable](a, b []T) []T
Difference returns elements in a that are not in b.
Example:
diff := Difference([]int{1, 2, 3}, []int{2, 3, 4})
// diff = [1]
func Drop ¶
Drop returns elements after skipping the first n. If n >= len(s), returns empty slice.
Example:
rest := Drop([]int{1, 2, 3, 4, 5}, 2)
// rest = [3, 4, 5]
func DropWhile ¶
DropWhile returns elements after dropping from the start while predicate returns true.
func Filter ¶
Filter returns a new slice containing only elements for which the predicate returns true. Returns nil if the input slice is nil.
Example:
evens := Filter([]int{1, 2, 3, 4, 5}, func(n int) bool { return n%2 == 0 })
// evens = [2, 4]
func FilterInPlace ¶
FilterInPlace filters the slice in place, returning the modified slice. The underlying array is modified; elements are shifted to fill gaps. This avoids allocation but modifies the original slice.
Example:
nums := []int{1, 2, 3, 4, 5}
evens := FilterInPlace(nums, func(n int) bool { return n%2 == 0 })
// evens = [2, 4], nums[0:2] = [2, 4]
func Find ¶
Find returns the first element satisfying the predicate and true, or zero value and false.
Example:
first, ok := Find(users, func(u User) bool { return u.Age > 18 })
func FlatMap ¶
func FlatMap[T, U any](s []T, transform func(T) []U) []U
FlatMap applies a function that returns a slice and flattens the result.
Example:
words := FlatMap([]string{"hello world", "foo bar"}, func(s string) []string {
return strings.Split(s, " ")
})
// words = ["hello", "world", "foo", "bar"]
func Flatten ¶
func Flatten[T any](s [][]T) []T
Flatten converts a slice of slices into a single slice.
Example:
flat := Flatten([][]int{{1, 2}, {3}, {4, 5}})
// flat = [1, 2, 3, 4, 5]
func ForEach ¶
func ForEach[T any](s []T, fn func(T))
ForEach calls a function for each element.
Example:
ForEach(items, func(item Item) { process(item) })
func ForEachWithIndex ¶
ForEachWithIndex calls a function for each element with its index.
func GroupBy ¶
func GroupBy[T any, K comparable](s []T, key func(T) K) map[K][]T
GroupBy groups elements by a key function.
Example:
nums := []int{1, 2, 3, 4, 5, 6}
groups := GroupBy(nums, func(n int) string {
if n%2 == 0 { return "even" }
return "odd"
})
// groups = map["even":[2, 4, 6] "odd":[1, 3, 5]]
func IndexOf ¶
func IndexOf[T comparable](s []T, target T) int
IndexOf returns the index of the first occurrence of target, or -1 if not found.
Example:
idx := IndexOf([]string{"a", "b", "c"}, "b")
// idx = 1
func IndexOfFunc ¶
IndexOfFunc returns the index of the first element satisfying the predicate, or -1.
func Insert ¶
Insert returns a new slice with value inserted at index. If index is out of bounds, appends to end.
Example:
inserted := Insert([]int{1, 3}, 1, 2)
// inserted = [1, 2, 3]
func Intersect ¶
func Intersect[T comparable](a, b []T) []T
Intersect returns elements present in both slices. Result preserves order from the first slice.
Example:
common := Intersect([]int{1, 2, 3}, []int{2, 3, 4})
// common = [2, 3]
func LastIndexOf ¶
func LastIndexOf[T comparable](s []T, target T) int
LastIndexOf returns the index of the last occurrence of target, or -1 if not found.
func Map ¶
func Map[T, U any](s []T, transform func(T) U) []U
Map applies a transformation function to each element and returns a new slice. Returns nil if the input slice is nil.
Example:
doubled := Map([]int{1, 2, 3}, func(n int) int { return n * 2 })
// doubled = [2, 4, 6]
func MapErr ¶ added in v1.1.0
MapErr applies fn to each element of s and returns the transformed slice. Returns the first error encountered (with a nil result slice); returns nil result and nil error for a nil input slice.
This fills the gap left by Map: when the transform can fail (e.g. parsing, type conversion, validation) you previously had to write a manual loop.
Example:
nums, err := MapErr([]string{"1", "2", "three"}, strconv.Atoi)
// err != nil on the third element; nums is nil
func MapWithIndex ¶
MapWithIndex applies a transformation function that receives both index and element.
Example:
indexed := MapWithIndex([]string{"a", "b"}, func(i int, s string) string {
return fmt.Sprintf("%d:%s", i, s)
})
// indexed = ["0:a", "1:b"]
func Max ¶
Max returns the maximum element using natural ordering. Returns zero value and false for empty slices.
func Min ¶
Min returns the minimum element using natural ordering. Returns zero value and false for empty slices.
func MinFunc ¶
MinFunc returns the minimum element using a comparison function. cmp should return negative if a < b, zero if a == b, positive if a > b.
func Pad ¶
Pad extends a slice to the target length by appending the fill value. If slice is already >= length, returns a clone.
Example:
padded := Pad([]int{1, 2}, 5, 0)
// padded = [1, 2, 0, 0, 0]
func PadLeft ¶
PadLeft extends a slice by prepending the fill value.
Example:
padded := PadLeft([]int{1, 2}, 5, 0)
// padded = [0, 0, 0, 1, 2]
func Partition ¶
Partition splits a slice into two: elements matching the predicate and those that don't.
Example:
evens, odds := Partition([]int{1, 2, 3, 4}, func(n int) bool { return n%2 == 0 })
// evens = [2, 4], odds = [1, 3]
func Reduce ¶
func Reduce[T, U any](s []T, initial U, accumulator func(U, T) U) U
Reduce reduces a slice to a single value using an accumulator function.
Example:
sum := Reduce([]int{1, 2, 3, 4}, 0, func(acc, n int) int { return acc + n })
// sum = 10
func RemoveAt ¶
RemoveAt returns a new slice with the element at index removed. Returns nil if index is out of bounds.
Example:
removed := RemoveAt([]int{1, 2, 3}, 1)
// removed = [1, 3]
func RemoveFirst ¶
func RemoveFirst[T comparable](s []T, value T) []T
RemoveFirst returns a new slice with the first occurrence of value removed.
func RemoveValue ¶
func RemoveValue[T comparable](s []T, value T) []T
RemoveValue returns a new slice with all occurrences of value removed.
Example:
cleaned := RemoveValue([]int{1, 2, 3, 2}, 2)
// cleaned = [1, 3]
func Reverse ¶
func Reverse[T any](s []T) []T
Reverse returns a new slice with elements in reverse order.
Example:
rev := Reverse([]int{1, 2, 3})
// rev = [3, 2, 1]
func ReverseInPlace ¶
func ReverseInPlace[T any](s []T) []T
ReverseInPlace reverses the slice in place and returns it.
Example:
nums := []int{1, 2, 3}
ReverseInPlace(nums)
// nums = [3, 2, 1]
func SeedShuffle ¶
func SeedShuffle(seed uint64)
SeedShuffle sets the seed for ShuffleInPlace. Useful for deterministic tests.
func Shuffle ¶
func Shuffle[T any](s []T) []T
Shuffle returns a new slice with elements in random order. Uses math/rand (NOT crypto/rand) for performance; not suitable for security-sensitive use.
For a deterministic shuffle use ShuffleWithSeed; for crypto-secure shuffling use randutil.Shuffle.
func ShuffleInPlace ¶
func ShuffleInPlace[T any](s []T)
ShuffleInPlace shuffles the slice in place using Fisher-Yates algorithm. Uses math/rand for performance; use Shuffle for crypto-secure randomness.
func Take ¶
Take returns the first n elements. If n > len(s), returns all elements.
Example:
first := Take([]int{1, 2, 3, 4, 5}, 3)
// first = [1, 2, 3]
func TakeLast ¶
TakeLast returns the last n elements.
Example:
last := TakeLast([]int{1, 2, 3, 4, 5}, 3)
// last = [3, 4, 5]
func TakeWhile ¶
TakeWhile returns elements from the start while predicate returns true.
Example:
result := TakeWhile([]int{1, 2, 3, 4, 1}, func(n int) bool { return n < 3 })
// result = [1, 2]
func Union ¶
func Union[T comparable](a, b []T) []T
Union returns all unique elements from both slices.
Example:
all := Union([]int{1, 2}, []int{2, 3})
// all = [1, 2, 3]
func Unique ¶
func Unique[T comparable](s []T) []T
Unique returns a new slice with duplicate elements removed. The first occurrence of each element is kept; order is preserved.
Example:
unique := Unique([]int{1, 2, 2, 3, 1})
// unique = [1, 2, 3]
func UniqueFunc ¶
func UniqueFunc[T any, K comparable](s []T, key func(T) K) []T
UniqueFunc returns a new slice with duplicates removed based on a key function. Elements with the same key are considered duplicates; first occurrence is kept.
Example:
type User struct { ID int; Name string }
users := []User{{1, "Alice"}, {2, "Bob"}, {1, "Alice2"}}
unique := UniqueFunc(users, func(u User) int { return u.ID })
// unique = [{1, "Alice"}, {2, "Bob"}]
Types ¶
This section is empty.