Skip to content

bborbe/collection

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

55 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors