sliceutil

package
v1.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 23, 2026 License: MIT Imports: 3 Imported by: 0

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

Constants

This section is empty.

Variables

This section is empty.

Functions

func All

func All[T any](s []T, predicate func(T) bool) bool

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

func Any[T any](s []T, predicate func(T) bool) bool

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

func Chunk[T any](s []T, size int) [][]T

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

func CompactFunc[T any](s []T, eq func(T, T) bool) []T

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

func ContainsFunc[T any](s []T, predicate func(T) bool) bool

ContainsFunc reports whether any element satisfies the predicate.

Example:

hasNegative := ContainsFunc(nums, func(n int) bool { return n < 0 })

func Count

func Count[T any](s []T, predicate func(T) bool) int

Count returns the number of elements satisfying the predicate.

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

func Drop[T any](s []T, n int) []T

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 DropLast

func DropLast[T any](s []T, n int) []T

DropLast returns elements after removing the last n.

func DropWhile

func DropWhile[T any](s []T, predicate func(T) bool) []T

DropWhile returns elements after dropping from the start while predicate returns true.

func Equal

func Equal[T comparable](a, b []T) bool

Equal reports whether two slices are equal.

func EqualFunc

func EqualFunc[T, U any](a []T, b []U, eq func(T, U) bool) bool

EqualFunc reports whether two slices are equal using a custom comparison.

func Filter

func Filter[T any](s []T, predicate func(T) bool) []T

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

func FilterInPlace[T any](s []T, predicate func(T) bool) []T

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

func Find[T any](s []T, predicate func(T) bool) (T, bool)

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 FindLast

func FindLast[T any](s []T, predicate func(T) bool) (T, bool)

FindLast returns the last element satisfying the predicate.

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

func ForEachWithIndex[T any](s []T, fn func(int, T))

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

func IndexOfFunc[T any](s []T, predicate func(T) bool) int

IndexOfFunc returns the index of the first element satisfying the predicate, or -1.

func Insert

func Insert[T any](s []T, index int, value T) []T

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

func MapErr[T, U any](s []T, fn func(T) (U, error)) ([]U, error)

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

func MapWithIndex[T, U any](s []T, transform func(int, T) U) []U

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

func Max[T cmp.Ordered](s []T) (T, bool)

Max returns the maximum element using natural ordering. Returns zero value and false for empty slices.

func MaxFunc

func MaxFunc[T any](s []T, cmpFn func(a, b T) int) (T, bool)

MaxFunc returns the maximum element using a comparison function.

func Min

func Min[T cmp.Ordered](s []T) (T, bool)

Min returns the minimum element using natural ordering. Returns zero value and false for empty slices.

func MinFunc

func MinFunc[T any](s []T, cmpFn func(a, b T) int) (T, bool)

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 None

func None[T any](s []T, predicate func(T) bool) bool

None returns true if no elements satisfy the predicate. Returns true for empty slices.

func Pad

func Pad[T any](s []T, length int, fill T) []T

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

func PadLeft[T any](s []T, length int, fill T) []T

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

func Partition[T any](s []T, predicate func(T) bool) (matching, notMatching []T)

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

func RemoveAt[T any](s []T, index int) []T

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

func Take[T any](s []T, n int) []T

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

func TakeLast[T any](s []T, n int) []T

TakeLast returns the last n elements.

Example:

last := TakeLast([]int{1, 2, 3, 4, 5}, 3)
// last = [3, 4, 5]

func TakeWhile

func TakeWhile[T any](s []T, predicate func(T) bool) []T

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"}]

func Zip

func Zip[T, U any](a []T, b []U) [][2]any

Zip combines two slices into pairs. Stops at the shorter slice.

Example:

type Pair[T, U any] struct { First T; Second U }
pairs := Zip([]int{1, 2}, []string{"a", "b"})
// pairs = [{1, "a"}, {2, "b"}]

func ZipWith

func ZipWith[T, U, V any](a []T, b []U, combine func(T, U) V) []V

ZipWith combines two slices using a function.

Example:

sums := ZipWith([]int{1, 2, 3}, []int{4, 5, 6}, func(a, b int) int { return a + b })
// sums = [5, 7, 9]

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL