Documentation
¶
Overview ¶
Package collection provides a type-safe, ergonomic wrapper over Go slices, modelled on Laravel's Collections but idiomatic Go. It leans on generics and favours immutability: chainable methods return a new Collection instead of mutating the receiver's backing array.
Because Go methods cannot introduce new type parameters, the API is split in two:
- Same-type operations are methods on Collection[T] and return Collection[T] so they chain: Filter, Reject, Map, Sort, Take, ...
- Type-changing operations are free functions (Map, FlatMap, Reduce, GroupBy, KeyBy, Pluck, ...) because the result element type differs from T.
Usage:
nums := collection.New(1, 2, 3, 4, 5, 6)
even := nums.
Filter(func(n int) bool { return n%2 == 0 }).
SortDesc().
Take(2).
All() // []int{6, 4}
type User struct {
Name string
Age int
}
users := collection.New(
User{"Ada", 36}, User{"Linus", 54}, User{"Grace", 36},
)
byAge := collection.GroupBy(users, func(u User) int { return u.Age })
names := collection.Map(users, func(u User) string { return u.Name }).All()
Immutability: methods that reshape the collection (Filter, Map, Sort, Reverse, ...) copy the backing slice so the original Collection and any slice passed to From is never modified. The only mutating helpers are Push and Prepend, and even those return a fresh Collection. Each and Tap iterate without copying and are the only way to observe elements in place.
Index ¶
- func Associate[T any, K comparable, V any](c Collection[T], fn func(T) (K, V)) map[K]V
- func Avg[T Number](c Collection[T]) (float64, bool)
- func Contains[T comparable](c Collection[T], target T) bool
- func GroupBy[T any, K comparable](c Collection[T], keyFn func(T) K) map[K]Collection[T]
- func KeyBy[T any, K comparable](c Collection[T], keyFn func(T) K) map[K]T
- func Max[T cmp.Ordered](c Collection[T]) (T, bool)
- func Min[T cmp.Ordered](c Collection[T]) (T, bool)
- func Reduce[T, U any](c Collection[T], init U, fn func(acc U, v T) U) U
- func Sum[T Number](c Collection[T]) T
- func SumBy[T any, N Number](c Collection[T], fn func(T) N) N
- type Collection
- func ChunkInto[T any](c Collection[T], size int) Collection[Collection[T]]
- func Collect[T any](items []T) Collection[T]
- func FlatMap[T, U any](c Collection[T], fn func(T) []U) Collection[U]
- func From[T any](items []T) Collection[T]
- func FromSeq[T any](seq iter.Seq[T]) Collection[T]
- func Map[T, U any](c Collection[T], fn func(T) U) Collection[U]
- func New[T any](items ...T) Collection[T]
- func Pluck[T, U any](c Collection[T], fn func(T) U) Collection[U]
- func SortByKey[T any, K cmp.Ordered](c Collection[T], keyFn func(T) K) Collection[T]
- func SortOrdered[T cmp.Ordered](c Collection[T]) Collection[T]
- func Unique[T comparable](c Collection[T]) Collection[T]
- func (c Collection[T]) All() []T
- func (c Collection[T]) Chunk(size int) [][]T
- func (c Collection[T]) ContainsBy(pred func(T) bool) bool
- func (c Collection[T]) Count() int
- func (c Collection[T]) Each(fn func(i int, v T)) Collection[T]
- func (c Collection[T]) Filter(keep func(T) bool) Collection[T]
- func (c Collection[T]) First() (T, bool)
- func (c Collection[T]) FirstWhere(pred func(T) bool) (T, bool)
- func (c Collection[T]) Get(i int) (T, bool)
- func (c Collection[T]) IsEmpty() bool
- func (c Collection[T]) IsNotEmpty() bool
- func (c Collection[T]) Last() (T, bool)
- func (c Collection[T]) Len() int
- func (c Collection[T]) Map(fn func(T) T) Collection[T]
- func (c Collection[T]) Merge(other Collection[T]) Collection[T]
- func (c Collection[T]) Partition(pred func(T) bool) (Collection[T], Collection[T])
- func (c Collection[T]) Prepend(items ...T) Collection[T]
- func (c Collection[T]) Push(items ...T) Collection[T]
- func (c Collection[T]) Reject(drop func(T) bool) Collection[T]
- func (c Collection[T]) Reverse() Collection[T]
- func (c Collection[T]) Seq() iter.Seq[T]
- func (c Collection[T]) Seq2() iter.Seq2[int, T]
- func (c Collection[T]) Skip(n int) Collection[T]
- func (c Collection[T]) Slice() []T
- func (c Collection[T]) Slicing(start, length int) Collection[T]
- func (c Collection[T]) Sort(less func(a, b T) bool) Collection[T]
- func (c Collection[T]) SortBy(keyFn func(T) int) Collection[T]
- func (c Collection[T]) Take(n int) Collection[T]
- func (c Collection[T]) Tap(fn func(Collection[T])) Collection[T]
- func (c Collection[T]) UniqueBy(keyFn func(T) any) Collection[T]
- type Number
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Associate ¶
func Associate[T any, K comparable, V any](c Collection[T], fn func(T) (K, V)) map[K]V
Associate builds a map from the collection by deriving a key/value pair from each element. Later elements overwrite earlier ones on key collision.
func Avg ¶
func Avg[T Number](c Collection[T]) (float64, bool)
Avg returns the mean of the elements as a float64 and true. For an empty collection it returns 0 and false.
func Contains ¶
func Contains[T comparable](c Collection[T], target T) bool
Contains reports whether the collection holds target. T must be comparable; for non-comparable types or custom predicates use Collection.ContainsBy.
func GroupBy ¶
func GroupBy[T any, K comparable](c Collection[T], keyFn func(T) K) map[K]Collection[T]
GroupBy partitions the collection into a map keyed by keyFn. Each bucket is a Collection preserving the original relative order of its elements.
Example ¶
package main
import (
"fmt"
"github.com/devituz/lagodev/collection"
)
func main() {
type product struct {
Name string
Category string
}
products := collection.New(
product{"Pen", "office"},
product{"Desk", "furniture"},
product{"Stapler", "office"},
)
byCat := collection.GroupBy(products, func(p product) string { return p.Category })
names := collection.Map(byCat["office"], func(p product) string { return p.Name })
fmt.Println(names.All())
}
Output: [Pen Stapler]
func KeyBy ¶
func KeyBy[T any, K comparable](c Collection[T], keyFn func(T) K) map[K]T
KeyBy indexes the collection by keyFn. When two elements share a key, the later element wins (matching Laravel's keyBy semantics).
func Max ¶
func Max[T cmp.Ordered](c Collection[T]) (T, bool)
Max returns the largest element and true, or the zero value and false when the collection is empty.
func Min ¶
func Min[T cmp.Ordered](c Collection[T]) (T, bool)
Min returns the smallest element and true, or the zero value and false when the collection is empty.
func Reduce ¶
func Reduce[T, U any](c Collection[T], init U, fn func(acc U, v T) U) U
Reduce folds the collection into a single value of type U, starting from init and applying fn for each element in order.
func Sum ¶
func Sum[T Number](c Collection[T]) T
Sum returns the arithmetic sum of all elements. The sum of an empty collection is the zero value of T.
func SumBy ¶
func SumBy[T any, N Number](c Collection[T], fn func(T) N) N
SumBy sums the numeric value derived from each element by fn.
Types ¶
type Collection ¶
type Collection[T any] struct { // contains filtered or unexported fields }
Collection wraps a slice of T and provides chainable, mostly-immutable operations over it. The zero value is an empty, ready-to-use collection.
Example ¶
package main
import (
"fmt"
"github.com/devituz/lagodev/collection"
)
func main() {
result := collection.New(1, 2, 3, 4, 5, 6).
Filter(func(n int) bool { return n%2 == 0 }).
Map(func(n int) int { return n * n }).
SortBy(func(n int) int { return -n }).
Take(2).
All()
fmt.Println(result)
}
Output: [36 16]
func ChunkInto ¶
func ChunkInto[T any](c Collection[T], size int) Collection[Collection[T]]
ChunkInto splits c into groups of at most size and returns each group wrapped in its own Collection, all held by an outer Collection. This is the free-function form of Chunk; it lives outside the Collection method set to avoid the generic instantiation cycle that Collection[Collection[T]] would cause if exposed as a method. A size <= 0 yields an empty outer Collection.
func Collect ¶
func Collect[T any](items []T) Collection[T]
Collect is an alias for From, mirroring Laravel's collect() helper.
func FlatMap ¶
func FlatMap[T, U any](c Collection[T], fn func(T) []U) Collection[U]
FlatMap applies fn to every element, where fn returns a slice, and concatenates all results into a single Collection[U].
func From ¶
func From[T any](items []T) Collection[T]
From wraps an existing slice. The slice is copied so later mutations of the argument do not leak into the Collection (and vice versa).
func FromSeq ¶
func FromSeq[T any](seq iter.Seq[T]) Collection[T]
FromSeq drains an iter.Seq[T] into a new Collection.
func Map ¶
func Map[T, U any](c Collection[T], fn func(T) U) Collection[U]
Map applies fn to every element of c and returns a new Collection whose element type is U. This is the type-changing counterpart to the same-type Collection.Map method.
func New ¶
func New[T any](items ...T) Collection[T]
New builds a Collection from the given variadic items.
func Pluck ¶
func Pluck[T, U any](c Collection[T], fn func(T) U) Collection[U]
Pluck extracts a single derived value from each element and returns them as a Collection[U], preserving order.
func SortByKey ¶
func SortByKey[T any, K cmp.Ordered](c Collection[T], keyFn func(T) K) Collection[T]
SortByKey returns a new Collection sorted ascending by the ordered key produced by keyFn.
func SortOrdered ¶
func SortOrdered[T cmp.Ordered](c Collection[T]) Collection[T]
SortOrdered returns a new Collection sorted ascending using the natural order of an ordered element type. The original collection is left untouched.
func Unique ¶
func Unique[T comparable](c Collection[T]) Collection[T]
Unique returns a new Collection with duplicate elements removed. The first occurrence of each value is kept and order is preserved. T must be comparable.
func (Collection[T]) All ¶
func (c Collection[T]) All() []T
All returns the underlying slice. The returned slice is a copy, so callers may mutate it freely without affecting the Collection. An empty collection yields a non-nil, zero-length slice.
func (Collection[T]) Chunk ¶
func (c Collection[T]) Chunk(size int) [][]T
Chunk splits the collection into consecutive groups of at most size elements, returned as [][]T. A size <= 0 yields a nil result. Each chunk is an independent copy of the underlying data.
[][]T is used rather than Collection[Collection[T]] because instantiating a Collection with itself as its type argument triggers a generic instantiation cycle. Wrap the result with ChunkInto if a Collection-of-Collections is needed at a call site.
func (Collection[T]) ContainsBy ¶
func (c Collection[T]) ContainsBy(pred func(T) bool) bool
ContainsBy reports whether any element satisfies pred.
func (Collection[T]) Each ¶
func (c Collection[T]) Each(fn func(i int, v T)) Collection[T]
Each invokes fn for every element, in order, passing the index and value. It returns the receiver unchanged so it can sit in a chain. fn observes the elements in place; do not retain pointers into the backing array.
func (Collection[T]) Filter ¶
func (c Collection[T]) Filter(keep func(T) bool) Collection[T]
Filter returns a new Collection containing only the elements for which keep returns true.
func (Collection[T]) First ¶
func (c Collection[T]) First() (T, bool)
First returns the first element and true, or the zero value and false when the collection is empty.
func (Collection[T]) FirstWhere ¶
func (c Collection[T]) FirstWhere(pred func(T) bool) (T, bool)
FirstWhere returns the first element satisfying pred and true, or the zero value and false when none match.
func (Collection[T]) Get ¶
func (c Collection[T]) Get(i int) (T, bool)
Get returns the element at index i and whether the index was in range.
func (Collection[T]) IsEmpty ¶
func (c Collection[T]) IsEmpty() bool
IsEmpty reports whether the collection has no elements.
func (Collection[T]) IsNotEmpty ¶
func (c Collection[T]) IsNotEmpty() bool
IsNotEmpty reports whether the collection has at least one element.
func (Collection[T]) Last ¶
func (c Collection[T]) Last() (T, bool)
Last returns the last element and true, or the zero value and false when the collection is empty.
func (Collection[T]) Map ¶
func (c Collection[T]) Map(fn func(T) T) Collection[T]
Map applies fn to every element and returns a new Collection of the same type. For transformations that change the element type, use the free function Map instead.
func (Collection[T]) Merge ¶
func (c Collection[T]) Merge(other Collection[T]) Collection[T]
Merge returns a new Collection with the elements of other appended after the receiver's elements.
func (Collection[T]) Partition ¶
func (c Collection[T]) Partition(pred func(T) bool) (Collection[T], Collection[T])
Partition splits the collection into two: the first holds elements for which pred returns true, the second holds the rest. Order is preserved within each.
func (Collection[T]) Prepend ¶
func (c Collection[T]) Prepend(items ...T) Collection[T]
Prepend returns a new Collection with the given items inserted at the front, in the order supplied.
func (Collection[T]) Push ¶
func (c Collection[T]) Push(items ...T) Collection[T]
Push returns a new Collection with the given items appended.
func (Collection[T]) Reject ¶
func (c Collection[T]) Reject(drop func(T) bool) Collection[T]
Reject is the inverse of Filter: it keeps elements for which drop returns false.
func (Collection[T]) Reverse ¶
func (c Collection[T]) Reverse() Collection[T]
Reverse returns a new Collection with the elements in reverse order.
func (Collection[T]) Seq ¶
func (c Collection[T]) Seq() iter.Seq[T]
Seq returns an iter.Seq[T] that yields each element in order, enabling range-over-func interop:
for v := range c.Seq() {
use(v)
}
The sequence iterates the live backing array; do not mutate the collection (e.g. via concurrent Push results) while ranging.
func (Collection[T]) Seq2 ¶
func (c Collection[T]) Seq2() iter.Seq2[int, T]
Seq2 returns an iter.Seq2[int, T] yielding (index, value) pairs in order.
func (Collection[T]) Skip ¶
func (c Collection[T]) Skip(n int) Collection[T]
Skip returns a new Collection with the first n elements dropped.
func (Collection[T]) Slicing ¶
func (c Collection[T]) Slicing(start, length int) Collection[T]
Slicing returns a new Collection covering the half-open range [start, start+length). A negative start counts from the end. A negative length means "to the end". Out-of-range bounds are clamped.
func (Collection[T]) Sort ¶
func (c Collection[T]) Sort(less func(a, b T) bool) Collection[T]
Sort returns a new Collection sorted in ascending order using less. The original collection is left untouched.
func (Collection[T]) SortBy ¶
func (c Collection[T]) SortBy(keyFn func(T) int) Collection[T]
SortBy returns a new Collection sorted ascending by the integer key produced by keyFn. For keys of other ordered types, use the package-level SortByKey.
func (Collection[T]) Take ¶
func (c Collection[T]) Take(n int) Collection[T]
Take returns a new Collection with the first n elements. A negative n takes the last |n| elements. n larger than the length takes everything.
func (Collection[T]) Tap ¶
func (c Collection[T]) Tap(fn func(Collection[T])) Collection[T]
Tap invokes fn with the whole collection (for side effects such as logging or debugging) and returns the receiver unchanged.
func (Collection[T]) UniqueBy ¶
func (c Collection[T]) UniqueBy(keyFn func(T) any) Collection[T]
UniqueBy returns a new Collection with duplicates removed, where uniqueness is determined by the comparable key returned by keyFn. The first occurrence of each key is kept and original order is preserved. For comparable element types, use the package-level Unique function.