Documentation
ยถ
Overview ยถ
Package list provides the list operations Go's stdlib leaves out โ set algebra, positional extraction, sampling, reordering, sorting, and substitution โ as plain generic functions on []T.
Categories ยถ
Set operations (T comparable): Unique, Union, Intersect, SymmetricDifference, Minus, Without. Treat slices as sets with predictable, stable output ordering.
Positional extraction (T any): FirstN, LastN, Between, At, First, Last. Extract by index or range. Negative indexes count from the end where meaningful; out-of-range indexes clamp or return (_, false) rather than panicking.
Sampling (T any): Sample, SampleN. Random element selection from math/rand/v2. Use crypto/rand directly if you need cryptographic entropy.
Reordering (T any): Reverse, Shuffle. Return new slices โ input is never mutated.
Sorting: Sort and SortDesc (T cmp.Ordered) for strings, numbers, and named types with ordered underlying kinds. SortBy (T any) for anything else via a caller-supplied comparator.
Zero stripping (T comparable): Compact. Removes every element equal to T's zero value.
Substitution (T comparable): Replace, ReplaceFirst. Value-based replacement; replace-by-index is intentionally a one-liner (s[i] = v) and not exposed.
Contracts ยถ
Every operation is nil-safe, never panics on nil or empty input, and never mutates its input. Empty results are returned as non-nil empty slices, so callers can range over them without nil checks.
All functions are safe for concurrent use on shared inputs: they never mutate their arguments, so multiple goroutines may call any function with overlapping or identical input slices without external synchronization. Each call allocates its own result slice, so callers may freely mutate the returned slice without affecting inputs or other callers' results.
NaN semantics for set operations ยถ
Float64 and float32 values follow Go's map-key semantics: NaN is never equal to NaN (including itself), so each NaN is a distinct map key. This has consequences for the set operations that use a map internally (Unique, Union, Intersect, SymmetricDifference, Minus, Without): none of them can match NaN against NaN, and none can deduplicate NaN values. The sort and positional operations are unaffected โ they do not use equality-based deduplication.
If you need NaN-aware set operations, pre-process your slice to replace NaNs with a canonical marker value.
Runtime panics from non-comparable interface values ยถ
Go's comparable constraint is checked at compile time, but interface types can carry dynamic values whose concrete type is not comparable (e.g., slices or maps stored in an any). Comparing such values causes a runtime panic. list does not recover from these panics โ it is the caller's responsibility to ensure interface slices contain only comparable dynamic values.
For documentation and examples, see https://github.com/bold-minds/list.
Index ยถ
- func At[T any](s []T, i int) (T, bool)
- func Between[T any](s []T, start, end int) []T
- func Compact[T comparable](s []T) []T
- func DropL[T any](s []T, n int) []T
- func DropR[T any](s []T, n int) []T
- func First[T any](s []T) (T, bool)
- func FirstN[T any](s []T, n int) []T
- func Intersect[T comparable](slices ...[]T) []T
- func Last[T any](s []T) (T, bool)
- func LastN[T any](s []T, n int) []T
- func Minus[T comparable](a, b []T) []T
- func Replace[T comparable](s []T, old, newVal T) []T
- func ReplaceFirst[T comparable](s []T, old, newVal T) []T
- func Reverse[T any](s []T) []T
- func Sample[T any](s []T) (T, bool)
- func SampleN[T any](s []T, n int) []T
- func Shuffle[T any](s []T) []T
- func Sort[T cmp.Ordered](s []T) []T
- func SortBy[T any](s []T, less func(a, b T) int) []T
- func SortDesc[T cmp.Ordered](s []T) []T
- func SymmetricDifference[T comparable](a, b []T) []T
- func Union[T comparable](slices ...[]T) []T
- func Unique[T comparable](s []T) []T
- func Without[T comparable](s []T, items ...T) []T
Constants ยถ
This section is empty.
Variables ยถ
This section is empty.
Functions ยถ
func At ยถ added in v0.2.0
At returns the element at index i and whether the index was in range. Negative indexes count from the end: At(s, -1) returns the last element. Returns (zero, false) for an empty slice or out-of-range index.
func Between ยถ added in v0.2.0
Between returns a new slice containing s[start:end], clamped to valid bounds. Negative start is clamped to 0; end greater than len(s) is clamped to len(s). If the resulting range is empty or inverted (start >= end after clamping), an empty slice is returned.
Unlike Go's native slice expression, Between never panics on out-of-range indexes.
func Compact ยถ added in v0.2.0
func Compact[T comparable](s []T) []T
Compact returns a new slice with every element equal to T's zero value removed. The zero value is whatever Go produces for `var v T`: `""` for strings, `0` for numerics, `false` for bool, nil for pointers/maps/slices/interfaces, and the all-zero struct for structs with comparable fields.
Compact requires T comparable so zero detection is expressed in pure Go (no reflection). Input is not mutated.
This is distinct from stdlib slices.Compact, which removes CONSECUTIVE duplicates. Use list.Unique for order-preserving full deduplication and list.Compact for zero-value stripping.
func DropL ยถ added in v0.2.1
DropL returns a new slice with the first n elements removed. It is the complement of FirstN: FirstN keeps the head, DropL discards it. If n <= 0, DropL returns a full copy of s. If n >= len(s), it returns an empty slice. Input is never mutated.
list.DropL([]int{1, 2, 3, 4, 5}, 2) // [3 4 5]
list.DropL([]int{1, 2, 3}, 10) // []
list.DropL([]int{1, 2, 3}, 0) // [1 2 3]
func DropR ยถ added in v0.2.1
DropR returns a new slice with the last n elements removed. It is the complement of LastN: LastN keeps the tail, DropR discards it. If n <= 0, DropR returns a full copy of s. If n >= len(s), it returns an empty slice. Input is never mutated.
list.DropR([]int{1, 2, 3, 4, 5}, 2) // [1 2 3]
list.DropR([]int{1, 2, 3}, 10) // []
list.DropR([]int{1, 2, 3}, 0) // [1 2 3]
func First ยถ added in v0.2.0
First returns the first element of s and ok=true, or (zero, false) for an empty slice. Equivalent to At(s, 0).
func FirstN ยถ added in v0.2.0
FirstN returns a new slice containing the first n elements of s. If n <= 0 returns an empty slice. If n >= len(s) returns a copy of s.
func Intersect ยถ
func Intersect[T comparable](slices ...[]T) []T
Intersect returns the unique elements present in every provided slice. Order is taken from the first slice. Variadic โ a single-slice call is equivalent to Unique; a zero-slice call returns an empty slice. A nil or empty slice anywhere in the input causes the result to be empty, since no element can appear in every slice.
func Last ยถ added in v0.2.0
Last returns the last element of s and ok=true, or (zero, false) for an empty slice. Equivalent to At(s, -1).
func LastN ยถ added in v0.2.0
LastN returns a new slice containing the last n elements of s. If n <= 0 returns an empty slice. If n >= len(s) returns a copy of s.
func Minus ยถ
func Minus[T comparable](a, b []T) []T
Minus returns the unique elements of a that are not present in b. Order is taken from a. Binary โ always exactly two arguments. To subtract multiple slices, compose with Union:
list.Minus(a, list.Union(b, c, d))
func Replace ยถ added in v0.2.0
func Replace[T comparable](s []T, old, newVal T) []T
Replace returns a new slice in which every element equal to old is replaced with newVal. Input is not mutated.
Use stdlib `s[i] = v` directly for single-index replacement โ list does not ship a positional Replace because Go already has it in the language.
func ReplaceFirst ยถ added in v0.2.0
func ReplaceFirst[T comparable](s []T, old, newVal T) []T
ReplaceFirst returns a new slice in which the first element equal to old is replaced with newVal. Subsequent occurrences are left unchanged. If old is not found, the returned slice is a copy of s with no changes. Input is not mutated.
func Reverse ยถ added in v0.2.0
func Reverse[T any](s []T) []T
Reverse returns a new slice containing the elements of s in reverse order. Input is not mutated.
func Sample ยถ added in v0.2.0
Sample returns one uniformly-random element of s and ok=true, or (zero, false) for an empty slice. Uses math/rand/v2's top-level goroutine-safe source โ adequate for tests, fixtures, and UI randomization, but NOT for cryptographic purposes. Use crypto/rand directly if you need unpredictability guarantees.
func SampleN ยถ added in v0.2.0
SampleN returns n distinct elements chosen uniformly at random from s, in random order. If n <= 0 returns empty; if n >= len(s) returns a Shuffle'd copy of s (implicitly capping n at len(s)).
The algorithm is a FisherโYates partial shuffle: O(n) time, O(len(s)) space for the working copy.
func Shuffle ยถ added in v0.2.0
func Shuffle[T any](s []T) []T
Shuffle returns a new slice containing the elements of s in a uniformly-random order. Input is not mutated. Uses the same math/rand/v2 source as Sample โ adequate for tests and UI but not for cryptographic purposes.
func Sort ยถ added in v0.2.0
Sort returns a new slice containing the elements of s in ascending order. T must satisfy cmp.Ordered (strings, all integer widths, both float types, and named types with those underlying kinds). Input is not mutated.
NaN handling follows cmp.Compare: NaN sorts before every non-NaN value.
func SortBy ยถ added in v0.2.0
SortBy returns a new slice containing the elements of s sorted by the caller-supplied comparator. less must return negative / zero / positive for a<b / a==b / a>b, matching slices.SortFunc. Input is not mutated.
Use SortBy when T is not cmp.Ordered โ structs, interfaces, pointers, custom types with non-ordered underlying kinds โ or when the sort key is a derived field rather than the element itself.
func SortDesc ยถ added in v0.2.0
SortDesc returns a new slice containing the elements of s in descending order. T must satisfy cmp.Ordered. Input is not mutated.
NaN handling is the inverse of Sort: NaN sorts after every non-NaN value (because the comparator is reversed).
func SymmetricDifference ยถ added in v0.2.0
func SymmetricDifference[T comparable](a, b []T) []T
SymmetricDifference returns the unique elements present in a or b but not in both โ i.e., (a โช b) โ (a โฉ b). Order is taken from a first, then b. Binary โ always exactly two arguments.
func Union ยถ
func Union[T comparable](slices ...[]T) []T
Union returns the unique elements across all provided slices, preserving the order of first occurrence as each slice is walked in turn. Variadic โ accepts zero or more slices.
func Unique ยถ
func Unique[T comparable](s []T) []T
Unique returns a new slice with duplicate elements removed, preserving the order of first occurrence. Returns an empty (non-nil) slice for nil or empty input.
func Without ยถ
func Without[T comparable](s []T, items ...T) []T
Without returns a new slice with all occurrences of the specified items removed, preserving the order of remaining elements.
Unlike Unique/Union/Intersect/Minus, Without does NOT deduplicate remaining elements. If s contains duplicates of values that are not in items, those duplicates remain in the output. For dedup + removal, chain: list.Unique(list.Without(s, v)).
Types ยถ
This section is empty.