collection

package module
v1.10.0 Latest Latest
Warning

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

Go to latest
Published: Jul 28, 2025 License: BSD-2-Clause Imports: 7 Imported by: 6

README

Collection

A comprehensive Go library providing generic, type-safe collection utilities and data structures. Leverages Go generics for efficient slice operations, set management, channel processing, and pointer utilities.

Features

  • 🔧 Slice Operations: Filter, Map, Find, Contains, Unique, Reverse, Copy, Exclude, Join
  • 📦 Set Data Structure: Thread-safe generic set with mutex protection
  • ⚡ Channel Processing: Concurrent channel operations with context support
  • 🎯 Pointer Utilities: Generic Ptr/Unptr functions for easy pointer creation
  • ⚖️ Comparison Utilities: Generic equality and string comparison helpers

Installation

go get github.com/bborbe/collection

Quick Start

import "github.com/bborbe/collection"

// Filter slice elements
numbers := []int{1, 2, 3, 4, 5}
evens := collection.Filter(numbers, func(n int) bool { return n%2 == 0 })
// Result: [2, 4]

// Create and use a Set
set := collection.NewSet[string]()
set.Add("hello")
set.Add("world")
fmt.Println(set.Contains("hello")) // true

// Create pointers easily
name := "John"
namePtr := collection.Ptr(name) // *string pointing to "John"

API Reference

Slice Operations
Filter
func Filter[T any](list []T, match func(value T) bool) []T

Returns a new slice containing only elements that match the predicate.

users := []User{{Name: "Alice", Age: 25}, {Name: "Bob", Age: 17}}
adults := collection.Filter(users, func(u User) bool { return u.Age >= 18 })
Find
func Find[T any](list []T, match func(value T) bool) (*T, error)

Returns the first element matching the predicate, or NotFoundError.

user, err := collection.Find(users, func(u User) bool { return u.Name == "Alice" })
if err != nil {
    // Handle not found
}
Map
func Map[T any](list []T, fn func(value T) error) error

Applies a function to each element in the slice, returning the first error encountered.

err := collection.Map(users, func(u User) error {
    return validateUser(u)
})
Unique
func Unique[T comparable](list []T) []T

Returns a new slice with duplicate elements removed, preserving order.

numbers := []int{1, 2, 2, 3, 3, 3}
unique := collection.Unique(numbers) // [1, 2, 3]
Contains
func Contains[T comparable](list []T, search T) bool
func ContainsAll[T comparable](list []T, search []T) bool

Check if slice contains specific element(s).

fruits := []string{"apple", "banana", "cherry"}
hasApple := collection.Contains(fruits, "apple") // true
hasAll := collection.ContainsAll(fruits, []string{"apple", "banana"}) // true
Reverse
func Reverse[T any](list []T) []T

Returns a new slice with elements in reverse order.

numbers := []int{1, 2, 3}
reversed := collection.Reverse(numbers) // [3, 2, 1]
Copy
func Copy[T any](list []T) []T

Creates a shallow copy of the slice.

Exclude
func Exclude[T comparable](list []T, exclude []T) []T

Returns a new slice excluding specified elements.

numbers := []int{1, 2, 3, 4, 5}
filtered := collection.Exclude(numbers, []int{2, 4}) // [1, 3, 5]
Join
func Join[T ~string](list []T, separator string) string

Joins string-like elements with a separator.

words := []string{"hello", "world", "!"}
sentence := collection.Join(words, " ") // "hello world !"
Set Data Structure
Creating Sets
func NewSet[T comparable]() Set[T]

Creates a new thread-safe generic set.

stringSet := collection.NewSet[string]()
intSet := collection.NewSet[int]()
Set Operations
type Set[T comparable] interface {
    Add(element T)
    Remove(element T) 
    Contains(element T) bool
    Slice() []T
    Length() int
}

Example usage:

set := collection.NewSet[string]()
set.Add("apple")
set.Add("banana")
set.Add("apple") // Duplicate, ignored

fmt.Println(set.Length()) // 2
fmt.Println(set.Contains("apple")) // true
fmt.Println(set.Slice()) // ["apple", "banana"] (order not guaranteed)

set.Remove("apple")
fmt.Println(set.Length()) // 1
Pointer Utilities
Ptr
func Ptr[T any](value T) *T

Creates a pointer to the given value.

name := "John"
namePtr := collection.Ptr(name) // *string

age := 25
agePtr := collection.Ptr(age) // *int
Unptr
func Unptr[T any](ptr *T) T
func UnptrWithDefault[T any](ptr *T, defaultValue T) T

Dereferences pointers safely.

var namePtr *string = collection.Ptr("John")
name := collection.Unptr(namePtr) // "John"

var nilPtr *string
name := collection.UnptrWithDefault(nilPtr, "Anonymous") // "Anonymous"
Channel Processing
ChannelFnMap
func ChannelFnMap[T interface{}](
    ctx context.Context,
    getFn func(ctx context.Context, ch chan<- T) error,
    mapFn func(ctx context.Context, t T) error,
) error

Processes data from a producer function through a mapper function concurrently.

err := collection.ChannelFnMap(
    ctx,
    func(ctx context.Context, ch chan<- int) error {
        for i := 0; i < 100; i++ {
            select {
            case ch <- i:
            case <-ctx.Done():
                return ctx.Err()
            }
        }
        return nil
    },
    func(ctx context.Context, num int) error {
        fmt.Printf("Processing: %d\n", num)
        return nil
    },
)
ChannelFnList & ChannelFnCount
func ChannelFnList[T any](ctx context.Context, getFn func(ctx context.Context, ch chan<- T) error) ([]T, error)
func ChannelFnCount[T any](ctx context.Context, getFn func(ctx context.Context, ch chan<- T) error) (int, error)

Collect channel data into a slice or count items.

Comparison Utilities
Equal & Compare
func Equal[T comparable](a, b T) bool
func Compare[T ~string](a, b T) int

Generic comparison functions for any comparable types.

Advanced Examples

Processing Large Datasets Concurrently
ctx := context.Background()

// Process items concurrently with automatic batching
err := collection.ChannelFnMap(
    ctx,
    func(ctx context.Context, ch chan<- WorkItem) error {
        return loadWorkItems(ctx, ch) // Your data loading logic
    },
    func(ctx context.Context, item WorkItem) error {
        return processWorkItem(ctx, item) // Your processing logic
    },
)
Building Complex Data Pipelines
// Load raw data
rawData := loadRawData()

// Filter valid entries
validData := collection.Filter(rawData, func(item DataItem) bool {
    return item.IsValid()
})

// Remove duplicates
uniqueData := collection.Unique(validData)

// Find specific items
importantItem, err := collection.Find(uniqueData, func(item DataItem) bool {
    return item.Priority == "high"
})

// Create a set for fast lookups
processedIDs := collection.NewSet[string]()
for _, item := range uniqueData {
    processedIDs.Add(item.ID)
}

Requirements

  • Go 1.24.5 or later
  • Support for Go generics

Dependencies

  • github.com/bborbe/errors - Enhanced error handling
  • github.com/bborbe/run - Concurrent execution utilities

Testing

go test ./...

License

BSD-style license. See LICENSE file for details.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var NotFoundError = stderrors.New("not found")

Functions

func ChannelFnCount added in v1.1.0

func ChannelFnCount[T interface{}](
	ctx context.Context,
	fn func(ctx context.Context, ch chan<- T) error,
) (int, error)

func ChannelFnList

func ChannelFnList[T interface{}](
	ctx context.Context,
	fn func(ctx context.Context, ch chan<- T) error,
) ([]T, error)

func ChannelFnMap

func ChannelFnMap[T interface{}](
	ctx context.Context,
	getFn func(ctx context.Context, ch chan<- T) error,
	mapFn func(ctx context.Context, t T) error,
) error

func Compare added in v1.6.0

func Compare[T ~string](a, b T) int

func Contains

func Contains[T comparable](list []T, value T) bool

func ContainsAll added in v1.2.0

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

ContainsAll returns true if all elements from slice b are present in slice a. It checks whether a is a superset of b (a ⊇ b). Empty slice b always returns true. Duplicate elements in b are treated as single elements.

func Copy added in v1.3.1

func Copy[T any](values []T) []T

func Equal added in v1.2.0

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

func Exclude

func Exclude[T comparable](list []T, excludes ...T) []T

func Filter

func Filter[T any](list []T, match func(value T) bool) []T

func Find

func Find[T any](list []T, match func(value T) bool) (*T, error)

func Join added in v1.7.0

func Join[T any](a []T, b []T) []T

Join allow to join two arrays into one new array

func Map added in v1.5.0

func Map[T any](list []T, fn func(value T) error) error

func Ptr

func Ptr[T any](value T) *T

func Reverse

func Reverse[T any](values []T) []T

func StreamList added in v1.8.0

func StreamList[T any](ctx context.Context, list []T, ch chan<- T) error

StreamList streams the given list into the given channel

func UnPtr

func UnPtr[T any](ptr *T) T

func Unique

func Unique[T comparable](list []T) []T

Types

type HasEqual added in v1.3.1

type HasEqual[V any] interface {
	Equal(value V) bool
}

type HasHashCode added in v1.3.1

type HasHashCode interface {
	HashCode() string
}

type Set added in v1.3.0

type Set[T comparable] interface {
	Add(element T)
	Remove(element T)
	Contains(element T) bool
	Slice() []T
	Length() int
}

func NewSet added in v1.3.0

func NewSet[T comparable]() Set[T]

type SetEqual added in v1.3.1

type SetEqual[T HasEqual[T]] interface {
	Add(element T)
	Remove(element T)
	Contains(element T) bool
	Slice() []T
	Length() int
}

func NewSetEqual added in v1.3.1

func NewSetEqual[T HasEqual[T]]() SetEqual[T]

type SetHashCode added in v1.3.1

type SetHashCode[T HasHashCode] interface {
	Add(element T)
	Remove(element T)
	Contains(element T) bool
	Slice() []T
	Length() int
}

func NewSetHashCode added in v1.3.1

func NewSetHashCode[T HasHashCode]() SetHashCode[T]

Jump to

Keyboard shortcuts

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