collections

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: May 20, 2026 License: MIT Imports: 4 Imported by: 0

README

go-collections

GitHub release (latest SemVer) Go Version Go Report Card GoDoc MIT License

A fluent, type-safe collection library for Go, inspired by Laravel Collections.

Built with Go generics (1.18+) — no reflection, no any casts at call-sites.

Installation

go get github.com/hymns/go-collections

Quick Start

import collections "github.com/hymns/go-collections"

type User struct {
    ID   int
    Name string
    Age  int
}

users := collections.New(
    User{1, "Alice", 30},
    User{2, "Bob", 20},
    User{3, "Carol", 25},
)

// Filter → Pluck → Sort in one chain
names := collections.SortByString(
    collections.Pluck(
        users.Filter(func(u User) bool { return u.Age >= 25 }),
        func(u User) string { return u.Name },
    ),
    func(s string) string { return s },
)

names.Each(func(name string) {
    fmt.Println(name) // Alice, Carol
})

Creating Collections

Function Description
New(items...) Create from variadic arguments
Collect(slice) Create from an existing slice
c1 := collections.New(1, 2, 3)
c2 := collections.Collect([]string{"a", "b", "c"})

Methods (chainable on *Collection[T])

Querying
Method Description
All() []T Return all items as a slice
Count() int Number of items
IsEmpty() bool True if no items
IsNotEmpty() bool True if at least one item
First(fn?) (T, bool) First item, optionally matching a predicate
Last(fn?) (T, bool) Last item, optionally matching a predicate
Nth(n int) (T, bool) Item at index n (0-based)
Contains(fn) bool True if any item satisfies fn
Every(fn) bool True if all items satisfy fn
Search(fn) (int, bool) Index of first item satisfying fn
Transforming
Method Description
Filter(fn) *Collection[T] Keep items that satisfy fn
Reject(fn) *Collection[T] Remove items that satisfy fn
Each(fn) *Collection[T] Iterate (returns self for chaining)
EachWithIndex(fn) *Collection[T] Iterate with index
Reverse() *Collection[T] Reverse order
Unique(keyFn) *Collection[T] Remove duplicates by key
Sort(less) *Collection[T] Sort with a custom comparator
Shuffle(randIntn) *Collection[T] Randomise order
Chunk(size) []*Collection[T] Split into smaller collections
Slicing
Method Description
Slice(offset, length) *Collection[T] Sub-collection from offset
Skip(n) *Collection[T] Drop first n items
Take(n) *Collection[T] Keep first n items
TakeLast(n) *Collection[T] Keep last n items
SkipUntil(fn) *Collection[T] Skip until predicate is true
TakeUntil(fn) *Collection[T] Take until predicate is true
Mutating (returns new collection)
Method Description
Push(items...) *Collection[T] Append to end
Prepend(items...) *Collection[T] Insert at start
Pop() (T, bool) Remove and return last item
Shift() (T, bool) Remove and return first item
Merge(other) *Collection[T] Combine two collections
Tap(fn) *Collection[T] Inspect without breaking the chain
Clone() *Collection[T] Deep copy — independent backing slice
Serialising
Method Description
ToJSON() ([]byte, error) Marshal to JSON
String() string JSON string (implements fmt.Stringer)

Top-level Generic Functions

Because Go methods cannot introduce new type parameters, operations that change the element type are top-level functions.

Transforming
// Map — transform each item
doubled := collections.Map(c, func(n int) int { return n * 2 })

// FlatMap — transform then flatten
tokens := collections.FlatMap(sentences, func(s string) []string {
    return strings.Fields(s)
})

// Pluck — extract a field
names := collections.Pluck(users, func(u User) string { return u.Name })

// Reduce — fold to a single value
sum := collections.Reduce(c, 0, func(acc, n int) int { return acc + n })
Grouping & Lookup
// GroupBy — map[K]*Collection[T]
byDept := collections.GroupBy(employees, func(e Employee) string { return e.Dept })

// KeyBy — map[K]T (last item wins on duplicate key)
byID := collections.KeyBy(users, func(u User) int { return u.ID })

// MapToMap — build a map with separate key and value functions
m := collections.MapToMap(users,
    func(u User) int    { return u.ID },
    func(u User) string { return u.Name },
)
Set Operations
key := func(n int) any { return n }

diff    := collections.Diff(a, b, key)      // items in a but not b
inter   := collections.Intersect(a, b, key) // items in both a and b
Partitioning
pass, fail := collections.Partition(scores, func(s int) bool { return s >= 50 })
Flattening
nested := collections.Collect([][]int{{1, 2}, {3, 4}})
flat   := collections.Flatten(nested) // [1, 2, 3, 4]
Numeric Aggregates

Works with any Number type (int, int64, float64, …).

sum       := collections.Sum(prices)
min, _    := collections.Min(prices)
max, _    := collections.Max(prices)
avg, _    := collections.Avg(prices)

// By a derived key
youngest, _ := collections.MinBy(users, func(u User) int { return u.Age })
oldest,   _ := collections.MaxBy(users, func(u User) int { return u.Age })
Sorting Helpers
// Sort by numeric key
sorted   := collections.SortBy(users, func(u User) int { return u.Age })
desc     := collections.SortByDesc(users, func(u User) int { return u.Age })

// Sort by string key
alpha    := collections.SortByString(users, func(u User) string { return u.Name })
Zipping
pairs := collections.Zip(names, scores) // *Collection[[2]any]
pairs.Each(func(p [2]any) {
    fmt.Println(p[0], p[1])
})

Full Example

package main

import (
    "fmt"
    collections "github.com/hymns/go-collections"
)

type Product struct {
    Name     string
    Category string
    Price    float64
    InStock  bool
}

func main() {
    products := collections.New(
        Product{"Laptop", "Electronics", 2999.00, true},
        Product{"Headphones", "Electronics", 299.00, false},
        Product{"Desk", "Furniture", 899.00, true},
        Product{"Chair", "Furniture", 459.00, true},
        Product{"Monitor", "Electronics", 1299.00, true},
    )

    // Available electronics under RM 2000, sorted by price
    result := collections.SortBy(
        products.
            Filter(func(p Product) bool { return p.InStock && p.Category == "Electronics" }).
            Reject(func(p Product) bool { return p.Price >= 2000 }),
        func(p Product) float64 { return p.Price },
    )

    result.Each(func(p Product) {
        fmt.Printf("%s — RM %.2f\n", p.Name, p.Price)
    })
    // Headphones — RM 299.00   (out of stock, filtered out)
    // Monitor    — RM 1299.00

    // Total value of in-stock items
    total := collections.Sum(
        collections.Pluck(
            products.Filter(func(p Product) bool { return p.InStock }),
            func(p Product) float64 { return p.Price },
        ),
    )
    fmt.Printf("Total stock value: RM %.2f\n", total)

    // Group by category
    byCategory := collections.GroupBy(products, func(p Product) string { return p.Category })
    for cat, group := range byCategory {
        fmt.Printf("%s: %d products\n", cat, group.Count())
    }
}

Benchmarks

Run with go test ./tests/... -bench=. -benchmem.

Benchmarked on Apple M3 Pro, Go 1.24, comparing against equivalent plain Go slice code.

vs Plain Go
Operation Size Collection Plain Go Overhead
Filter 100 249 ns 256 ns ~0%
10k 17.2 µs 17.2 µs ~0%
100k 212 µs 212 µs ~0%
Map 100 107 ns 113 ns ~0%
10k 6.7 µs 6.8 µs ~0%
100k 61 µs 65 µs ~0%
Reduce 100 34 ns 30 ns ~0%
10k 2.8 µs 2.8 µs ~0%
100k 28 µs 29 µs ~0%
Sort 100 3.7 µs 3.3 µs ~13%
10k 421 µs 377 µs ~12%
100k 4.4 ms 4.0 ms ~9%
GroupBy 100 7.6 µs 5.5 µs ~38%
10k 328 µs 172 µs ~91%
100k 2.8 ms 1.9 ms ~48%
Chain (Filter→Map→Sort) 100 2.2 µs 1.7 µs ~32%
10k 235 µs 200 µs ~17%
100k 2.6 ms 2.2 ms ~21%
Zero-allocation operations

Contains, Reduce, and Sum produce 0 allocations/op at all sizes.

Notes
  • Filter / Map — overhead is effectively zero; the abstraction is free.
  • Sort — ~10% overhead from the defensive copy that keeps the original collection immutable.
  • GroupBy — highest overhead because each group is wrapped in its own Collection. Use plain map if this is a hot path.
  • Chain — intermediate allocations add ~20% overhead vs a single-pass plain Go loop. Acceptable for most use cases.

Safety Guarantees

go-collections is fully immutable — every operation returns a new collection and never modifies the receiver or the original slice passed in. This is a deliberate design choice that sets it apart from samber/lo and goforj/collection for two specific operations.

Note on versions: The lo.Reverse mutation behaviour described here applies to samber/lo up to at least v1.x. Always check the changelog of the exact version you are pinning.

Performance tradeoff: Immutability means every operation allocates a new backing array. For the vast majority of use-cases this cost is negligible, but if Reverse or Chunk sits in a hot path, benchmark before committing to any library.


Reverse
Library Behaviour
go-collections Returns a new collection. Original is untouched. ✅
samber/lo Mutates the caller's slice in-place. ❌
goforj/collection Mutates the backing slice in-place, returns the same pointer. ❌
// lo — silent mutation
original := []int{1, 2, 3, 4, 5}
rev := lo.Reverse(original)
fmt.Println(original) // [5 4 3 2 1] — caller's slice is gone
fmt.Println(rev)      // [5 4 3 2 1] — same pointer as original

// goforj — same pointer returned; calling twice undoes the reversal
c := collection.New([]int{1, 2, 3, 4, 5})
rev := c.Reverse()
fmt.Println(c.Items())   // [5 4 3 2 1] — original mutated!
fmt.Println(rev.Items()) // [5 4 3 2 1] — same pointer as c

// go-collections — always safe
c := collections.New(1, 2, 3, 4, 5)
rev := c.Reverse()
fmt.Println(c.All())   // [1 2 3 4 5] — untouched
fmt.Println(rev.All()) // [5 4 3 2 1]

Chunk
Library Behaviour
go-collections Each chunk is an independent copy. ✅
samber/lo Each chunk is an independent copy. ✅
goforj/collection Chunks are sub-slices sharing the backing array — mutating a chunk mutates the original. ❌
// goforj — silent data corruption
c := collection.New([]int{1, 2, 3, 4, 5})
chunks := c.Chunk(2)
chunks[0][0] = 99
fmt.Println(c.Items()) // [99 2 3 4 5] — original corrupted

// go-collections — chunks are fully independent
c := collections.New(1, 2, 3, 4, 5)
chunks := c.Chunk(2)
chunks[0][0] = 99
fmt.Println(c.All()) // [1 2 3 4 5] — original intact

Achieving safe behaviour with lo and goforj

To get the same immutability guarantees, lo needs a manual copy before each call and goforj needs .Clone(). Without these steps, both produce the broken results shown above.

Reverse
// go-collections — works as-is
c := collections.New(1, 2, 3, 4, 5)
rev := c.Reverse()
fmt.Println(c.All())   // [1 2 3 4 5]
fmt.Println(rev.All()) // [5 4 3 2 1]

// lo — copy before each call
original := []int{1, 2, 3, 4, 5}
cp  := append([]int(nil), original...)
rev := lo.Reverse(cp)
fmt.Println(original) // [1 2 3 4 5]
fmt.Println(rev)      // [5 4 3 2 1]

// goforj — Clone() before each call
c   := collection.New([]int{1, 2, 3, 4, 5})
rev := c.Clone().Reverse()
fmt.Println(c.Items())   // [1 2 3 4 5]
fmt.Println(rev.Items()) // [5 4 3 2 1]
Reverse twice

Chaining two Reverse calls is where the difference between libraries becomes most visible.

// go-collections — each call returns a new collection; intermediate is always valid
c      := collections.New(1, 2, 3, 4, 5)
rev    := c.Reverse()
revrev := rev.Reverse()
fmt.Println(c.All())      // [1 2 3 4 5] — original untouched
fmt.Println(rev.All())    // [5 4 3 2 1] — intermediate preserved ✓
fmt.Println(revrev.All()) // [1 2 3 4 5]

// lo — rev is silently overwritten when passed back in
cp     := append([]int(nil), []int{1, 2, 3, 4, 5}...)
rev    := lo.Reverse(cp)  // cp → [5 4 3 2 1], rev == cp (same slice)
revrev := lo.Reverse(rev) // rev/cp → [1 2 3 4 5]
fmt.Println(rev)          // [1 2 3 4 5] — intermediate was silently overwritten

// lo — safe with a copy before every call
cp1    := append([]int(nil), []int{1, 2, 3, 4, 5}...)
rev    := lo.Reverse(cp1)
cp2    := append([]int(nil), rev...)
revrev := lo.Reverse(cp2)
fmt.Println(rev)    // [5 4 3 2 1] ✓
fmt.Println(revrev) // [1 2 3 4 5] ✓

// goforj — rev/revrev/c are all the same pointer
c      := collection.New([]int{1, 2, 3, 4, 5})
rev    := c.Reverse()       // mutates c, returns c
revrev := rev.Reverse()     // mutates c again, returns c
fmt.Println(rev.Items())    // [1 2 3 4 5] — rev was never [5 4 3 2 1]

// goforj — safe with Clone() before every call
c      := collection.New([]int{1, 2, 3, 4, 5})
rev    := c.Clone().Reverse()
revrev := rev.Clone().Reverse()
fmt.Println(rev.Items())    // [5 4 3 2 1] ✓
fmt.Println(revrev.Items()) // [1 2 3 4 5] ✓
Chunk
// go-collections — always safe
c := collections.New(1, 2, 3, 4, 5)
chunks := c.Chunk(2)
chunks[0][0] = 99
fmt.Println(c.All()) // [1 2 3 4 5]

// lo — also safe; lo copies each chunk internally
original := []int{1, 2, 3, 4, 5}
chunks := lo.Chunk(original, 2)
chunks[0][0] = 99
fmt.Println(original) // [1 2 3 4 5]

// goforj — must copy each sub-slice manually
c   := collection.New([]int{1, 2, 3, 4, 5})
raw := c.Chunk(2)
safe := make([][]int, len(raw))
for i, chunk := range raw {
    cp := make([]int, len(chunk))
    copy(cp, chunk)
    safe[i] = cp
}
safe[0][0] = 99
fmt.Println(c.Items()) // [1 2 3 4 5]

Why is go-collections slower on these two operations?

The speed difference is the direct cost of safety:

  • goforj.Reverse does N/2 in-place swaps (0 allocations). We allocate N elements and copy.
  • goforj.Chunk creates slice headers pointing into the original array (0 copies). We copy each chunk.

There is no algorithmic trick that closes this gap while preserving immutability. The benchmark penalty is the price paid for correctness.


License

Distributed under MIT License, please see license file within the code for more details.

Documentation

Overview

Package collections provides a fluent, chainable collection type for Go, inspired by Laravel Collections.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Avg

func Avg[T Number](c *Collection[T]) (float64, bool)

Avg returns the average of a numeric collection as float64. Returns 0 and false if the collection is empty.

func GroupBy

func GroupBy[T any, K comparable](c *Collection[T], fn func(T) K) map[K]*Collection[T]

GroupBy groups items by a key derived from fn, returning a map of collections.

byStatus := collections.GroupBy(orders, func(o Order) string { return o.Status })

func IndexOf

func IndexOf[T comparable](c *Collection[T], value T) (int, bool)

IndexOf returns the index of the first occurrence of value in the collection. Prefer this over Collection.Search for comparable types — avoids closure overhead.

func KeyBy

func KeyBy[T any, K comparable](c *Collection[T], fn func(T) K) map[K]T

KeyBy returns a map keyed by the result of fn. Later items overwrite earlier ones with the same key.

byID := collections.KeyBy(users, func(u User) int { return u.ID })

func MapToMap

func MapToMap[T any, K comparable, V any](c *Collection[T], keyFn func(T) K, valFn func(T) V) map[K]V

MapToMap converts a collection to a plain map using key and value extractor functions.

func Max

func Max[T Number](c *Collection[T]) (T, bool)

Max returns the maximum value in a numeric collection. Returns zero and false if the collection is empty.

func MaxBy

func MaxBy[T any, K Number](c *Collection[T], fn func(T) K) (T, bool)

MaxBy returns the item with the largest key, as derived by fn.

func Min

func Min[T Number](c *Collection[T]) (T, bool)

Min returns the minimum value in a numeric collection. Returns zero and false if the collection is empty.

func MinBy

func MinBy[T any, K Number](c *Collection[T], fn func(T) K) (T, bool)

MinBy returns the item with the smallest key, as derived by fn.

func Partition

func Partition[T any](c *Collection[T], fn func(T) bool) (*Collection[T], *Collection[T])

Partition splits the collection into two: items that pass and items that fail the predicate.

pass, fail := collections.Partition(scores, func(s int) bool { return s >= 50 })

func Reduce

func Reduce[T, U any](c *Collection[T], initial U, fn func(U, T) U) U

Reduce reduces the collection to a single value.

total := collections.Reduce(prices, 0.0, func(acc float64, p float64) float64 { return acc + p })

func SetExitFn

func SetExitFn(fn func())

SetExitFn overrides the function called by Dd. Pass nil to restore the default os.Exit(1). Intended for use in tests only.

func Sum

func Sum[T Number](c *Collection[T]) T

Sum returns the sum of all items in a numeric collection.

Types

type Collection

type Collection[T any] struct {
	// contains filtered or unexported fields
}

Collection is a generic, ordered list of items with a fluent interface.

func Collect

func Collect[T any](items []T) *Collection[T]

Collect creates a Collection from a slice.

func Diff

func Diff[T any](c *Collection[T], other *Collection[T], key func(T) any) *Collection[T]

Diff returns items in c that are not present in other, using the key function for comparison.

func FlatMap

func FlatMap[T, U any](c *Collection[T], fn func(T) []U) *Collection[U]

FlatMap transforms each item into a slice and flattens the results.

func Flatten

func Flatten[T any](c *Collection[[]T]) *Collection[T]

Flatten flattens one level of nested slices.

flat := collections.Flatten(collections.Collect([][]int{{1, 2}, {3, 4}}))

func Intersect

func Intersect[T any](c *Collection[T], other *Collection[T], key func(T) any) *Collection[T]

Intersect returns items in c that are also present in other, using the key function.

func Map

func Map[T, U any](c *Collection[T], fn func(T) U) *Collection[U]

Map transforms each item in the collection using fn, returning a new collection.

names := collections.Map(users, func(u User) string { return u.Name })

func New

func New[T any](items ...T) *Collection[T]

New creates a Collection from variadic items.

func Pluck

func Pluck[T, U any](c *Collection[T], fn func(T) U) *Collection[U]

Pluck extracts a single field from each item using fn.

ids := collections.Pluck(users, func(u User) int { return u.ID })

func SortBy

func SortBy[T any, K Number](c *Collection[T], fn func(T) K) *Collection[T]

SortBy returns a new collection sorted by the numeric key derived from fn (ascending).

func SortByDesc

func SortByDesc[T any, K Number](c *Collection[T], fn func(T) K) *Collection[T]

SortByDesc returns a new collection sorted by the numeric key (descending).

func SortByString

func SortByString[T any](c *Collection[T], fn func(T) string) *Collection[T]

SortByString returns a new collection sorted by a string key.

func UniqueComparable

func UniqueComparable[T comparable](c *Collection[T]) *Collection[T]

UniqueComparable removes duplicate items from a collection of comparable types. Prefer this over Collection.Unique when T is comparable — it uses map[T]struct{} instead of map[any]struct{}, avoiding per-element interface boxing.

nums := collections.UniqueComparable(collections.New(1, 2, 2, 3))

func Zip

func Zip[T, U any](c *Collection[T], other *Collection[U]) *Collection[[2]any]

Zip pairs each item in c with the corresponding item in other. The resulting collection stops at the shorter length.

func (*Collection[T]) All

func (c *Collection[T]) All() []T

All returns all items as a slice.

func (*Collection[T]) Chunk

func (c *Collection[T]) Chunk(size int) [][]T

Chunk splits the collection into slices of the given size.

func (*Collection[T]) Clone

func (c *Collection[T]) Clone() *Collection[T]

ToJSON serialises the collection to JSON bytes. Clone returns a new collection with an independent copy of the backing slice.

func (*Collection[T]) Contains

func (c *Collection[T]) Contains(fn func(T) bool) bool

Contains returns true if any item satisfies the predicate.

func (*Collection[T]) Count

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

Count returns the number of items.

func (*Collection[T]) Dd

func (c *Collection[T]) Dd()

Dd dumps the collection to stdout then exits the process (dump and die). Mirrors Laravel's dd() — for debugging only, never use in production.

func (*Collection[T]) Dump

func (c *Collection[T]) Dump() *Collection[T]

Dump prints the collection items as indented JSON to stdout and returns the collection unchanged, so it can be inserted anywhere in a chain.

collections.New(1, 2, 3).Filter(fn).Dump().Map(fn2)

func (*Collection[T]) DumpStr

func (c *Collection[T]) DumpStr() string

DumpStr returns the collection as an indented JSON string without printing. Useful for logging and snapshot tests.

func (*Collection[T]) Each

func (c *Collection[T]) Each(fn func(T)) *Collection[T]

Each calls fn for every item and returns the collection for chaining.

func (*Collection[T]) EachWithIndex

func (c *Collection[T]) EachWithIndex(fn func(int, T)) *Collection[T]

EachWithIndex calls fn with the index and item for every item.

func (*Collection[T]) Every

func (c *Collection[T]) Every(fn func(T) bool) bool

Every returns true if all items satisfy the predicate.

func (*Collection[T]) Filter

func (c *Collection[T]) Filter(fn func(T) bool) *Collection[T]

Filter returns a new collection with items that satisfy the predicate.

func (*Collection[T]) First

func (c *Collection[T]) First() (T, bool)

First returns the first item. Returns zero value and false if empty.

func (*Collection[T]) FirstWhere

func (c *Collection[T]) FirstWhere(fn func(T) bool) (T, bool)

FirstWhere returns the first item that satisfies fn.

func (*Collection[T]) IsEmpty

func (c *Collection[T]) IsEmpty() bool

IsEmpty returns true if the collection has no items.

func (*Collection[T]) IsNotEmpty

func (c *Collection[T]) IsNotEmpty() bool

IsNotEmpty returns true if the collection has at least one item.

func (*Collection[T]) Last

func (c *Collection[T]) Last() (T, bool)

Last returns the last item. Returns zero value and false if empty.

func (*Collection[T]) LastWhere

func (c *Collection[T]) LastWhere(fn func(T) bool) (T, bool)

LastWhere returns the last item that satisfies fn.

func (*Collection[T]) Merge

func (c *Collection[T]) Merge(other *Collection[T]) *Collection[T]

Merge returns a new collection combining the current items with another collection.

func (*Collection[T]) Nth

func (c *Collection[T]) Nth(n int) (T, bool)

Nth returns the item at index n (0-based). Returns zero value and false if out of range.

func (*Collection[T]) Pop

func (c *Collection[T]) Pop() (T, bool)

Pop removes and returns the last item.

func (*Collection[T]) Prepend

func (c *Collection[T]) Prepend(items ...T) *Collection[T]

Prepend inserts items at the beginning and returns a new collection.

func (*Collection[T]) Push

func (c *Collection[T]) Push(items ...T) *Collection[T]

Push appends items to the end and returns a new collection.

func (*Collection[T]) Reject

func (c *Collection[T]) Reject(fn func(T) bool) *Collection[T]

Reject returns a new collection with items that do NOT satisfy the predicate.

func (*Collection[T]) Reverse

func (c *Collection[T]) Reverse() *Collection[T]

Reverse returns a new collection with items in reverse order.

func (*Collection[T]) Search

func (c *Collection[T]) Search(fn func(T) bool) (int, bool)

Search returns the index of the first item that satisfies the predicate.

func (*Collection[T]) Shift

func (c *Collection[T]) Shift() (T, bool)

Shift removes and returns the first item.

func (*Collection[T]) Shuffle

func (c *Collection[T]) Shuffle(randIntn func(int) int) *Collection[T]

Shuffle returns a new collection with items in random order. Pass a seeded rand func, e.g. rand.Intn, for reproducibility.

func (*Collection[T]) Skip

func (c *Collection[T]) Skip(n int) *Collection[T]

Skip returns a new collection skipping the first n items.

func (*Collection[T]) SkipUntil

func (c *Collection[T]) SkipUntil(fn func(T) bool) *Collection[T]

SkipUntil skips items until the predicate is true, then returns the rest.

func (*Collection[T]) Slice

func (c *Collection[T]) Slice(offset, length int) *Collection[T]

Slice returns a new collection starting at offset with at most length items.

func (*Collection[T]) Sort

func (c *Collection[T]) Sort(less func(a, b T) bool) *Collection[T]

Sort returns a new collection sorted by the given less function.

func (*Collection[T]) String

func (c *Collection[T]) String() string

String returns the JSON representation of the collection.

func (*Collection[T]) Take

func (c *Collection[T]) Take(n int) *Collection[T]

Take returns a new collection with only the first n items.

func (*Collection[T]) TakeLast

func (c *Collection[T]) TakeLast(n int) *Collection[T]

TakeLast returns a new collection with only the last n items.

func (*Collection[T]) TakeUntil

func (c *Collection[T]) TakeUntil(fn func(T) bool) *Collection[T]

TakeUntil returns items until the predicate becomes true.

func (*Collection[T]) Tap

func (c *Collection[T]) Tap(fn func(*Collection[T])) *Collection[T]

Tap calls fn with the collection (for side effects / debugging) and returns the collection.

func (*Collection[T]) ToJSON

func (c *Collection[T]) ToJSON() ([]byte, error)

func (*Collection[T]) Unique

func (c *Collection[T]) Unique(key func(T) any) *Collection[T]

Unique returns a new collection with duplicate items removed, using a key function.

type Number

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

Number is a type constraint for numeric types.

Jump to

Keyboard shortcuts

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