collection

package
v0.23.0 Latest Latest
Warning

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

Go to latest
Published: Jun 24, 2026 License: MIT Imports: 3 Imported by: 0

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

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]) Count

func (c Collection[T]) Count() int

Count is an alias for Len.

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]) Len

func (c Collection[T]) Len() int

Len returns the number of elements.

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]) Slice

func (c Collection[T]) Slice() []T

Slice is an alias for All.

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.

type Number

type Number interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64 |
		~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
		~float32 | ~float64
}

Number is the set of types over which arithmetic aggregation (Sum, Avg) is defined.

Jump to

Keyboard shortcuts

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