slice

package
v0.11.0 Latest Latest
Warning

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

Go to latest
Published: Jan 23, 2026 License: MIT Imports: 0 Imported by: 0

README

slice: fluent collection operations

Eliminate loop bugs with type-safe collection operations. Method expressions make pipelines read like intent—fluent operations chain method calls on a single line, no intermediate variables, no loop scaffolding.

actives := slice.From(users).KeepIf(User.IsActive).ToString(User.GetName)

See the main README for when to use fluentfp and performance characteristics. See pkg.go.dev for complete API documentation. For function naming patterns, see Naming Functions for Higher-Order Functions.

Quick Start

go get github.com/binaryphile/fluentfp
import "github.com/binaryphile/fluentfp/slice"

// Filter and extract
names := slice.From(users).KeepIf(User.IsActive).ToString(User.GetName)

// Map to arbitrary type
users := slice.MapTo[User](emails).To(UserFromEmail)

// Reduce
total := slice.Fold(amounts, 0.0, sumFloat64)

Types

Mapper[T] wraps a slice for fluent operations. Create with From(), chain methods, use as a regular slice.

MapperTo[R,T] adds .To() for mapping to arbitrary type R. Create with MapTo[R]().

users := slice.From(rawUsers)       // Mapper[User]
names := users.ToString(User.Name)  // Mapper[string]

API Reference

Factory Functions
Function Signature Purpose Example
From From[T]([]T) Mapper[T] Create Mapper from slice slice.From(users)
MapTo MapTo[R,T]([]T) MapperTo[R,T] Create MapperTo for type R slice.MapTo[User](ids)
Mapper Methods
Method Signature Purpose Example
KeepIf .KeepIf(func(T) bool) Mapper[T] Keep matching actives = slice.From(users).KeepIf(User.IsActive)
RemoveIf .RemoveIf(func(T) bool) Mapper[T] Remove matching current = slice.From(users).RemoveIf(User.IsExpired)
TakeFirst .TakeFirst(n int) Mapper[T] First n elements top10 = slice.From(users).TakeFirst(10)
Convert .Convert(func(T) T) Mapper[T] Map to same type normalized = slice.From(users).Convert(User.Normalize)
ToString .ToString(func(T) string) Mapper[string] Map to string names = slice.From(users).ToString(User.Name)
ToInt .ToInt(func(T) int) Mapper[int] Map to int ages = slice.From(users).ToInt(User.Age)
Each .Each(func(T)) Side-effect iteration slice.From(users).Each(User.Save)
Len .Len() int Count elements count = slice.From(users).Len()

Other To[Type] methods: ToAny, ToBool, ToByte, ToError, ToFloat32, ToFloat64, ToInt32, ToInt64, ToRune

MapperTo Additional Method
Method Signature Purpose Example
To .To(func(T) R) Mapper[R] Map to type R users = slice.MapTo[User](ids).To(FetchUser)
Standalone Functions
Function Signature Purpose Example
Fold Fold[T,R]([]T, R, func(R,T) R) R Reduce to single value See Fold
Unzip2 Unzip2[T,A,B]([]T, func(T)A, func(T)B) (Mapper[A], Mapper[B]) Extract 2 fields names, ages = slice.Unzip2(users, User.Name, User.Age)
Unzip3 Unzip3[T,A,B,C](...) Extract 3 fields
Unzip4 Unzip4[T,A,B,C,D](...) Extract 4 fields
Type Aliases

For use with make(): Any, Bool, Byte, Error, Int, Rune, String

words := make(slice.String, 0, 10)

Method Expressions

Method expressions let you pass methods directly to higher-order functions:

slice.From(users).KeepIf(User.IsActive)  // User.IsActive is func(User) bool

Receiver type must match slice element type. Value receivers work with []T; pointer receivers require []*T:

// Works: value receiver + value slice
func (u User) IsActive() bool { return u.Active }
slice.From(users).KeepIf(User.IsActive)  // ✓

// Fails: pointer receiver + value slice
func (u *User) IsActive() bool { return u.Active }
slice.From(users).KeepIf(User.IsActive)  // ✗ type mismatch

Pipeline Formatting

Single operation — one line:

names := slice.From(users).ToString(User.GetName)

Multiple operations — one per line:

result := slice.From(items).
    KeepIf(Item.IsValid).
    RemoveIf(Item.IsExpired).
    ToInt(Item.Score)

Split at conceptual boundaries when chains get long:

validCurrent := slice.From(items).
    KeepIf(Item.IsValid).
    RemoveIf(Item.IsExpired)
scores := validCurrent.
    ToInt(Item.Score).
    KeepIf(aboveThreshold)

Patterns

Type Alias for Domain Slices
type SliceOfUsers = slice.Mapper[User]

var users SliceOfUsers = fetchUsers()
actives := users.KeepIf(User.IsActive)

Avoids repeated slice.From() calls.

Method Expression Chaining
devices := slice.From(rawDevices).
    Convert(Device.Normalize).
    KeepIf(Device.IsValid)
Field Extraction
macs := devices.ToString(Device.GetMAC)
Counting
activeCount := slice.From(users).KeepIf(User.IsActive).Len()

Note: Allocates intermediate slice. For hot paths, use a manual loop.

Fold
// sumFloat64 adds two float64 values.
sumFloat64 := func(acc, x float64) float64 { return acc + x }
total := slice.Fold(amounts, 0.0, sumFloat64)

// indexByMAC adds a device to the map keyed by its MAC address.
indexByMAC := func(m map[string]Device, d Device) map[string]Device {
    m[d.MAC] = d
    return m
}
byMAC := slice.Fold(devices, make(map[string]Device), indexByMAC)
Unzip

Extract multiple fields in one pass (more efficient than separate ToX calls):

leadTimes, deployFreqs, mttrs, cfrs := slice.Unzip4(history,
    Record.GetLeadTime,
    Record.GetDeployFreq,
    Record.GetMTTR,
    Record.GetChangeFailRate,
)
Zip (pair package)
import "github.com/binaryphile/fluentfp/tuple/pair"

pairs := pair.Zip(names, scores)
// []pair.X[string, int]{{V1: "Alice", V2: 95}, ...}

results := pair.ZipWith(names, scores, formatScore)
// []string{"Alice: 95", ...}

Both panic if slices have different lengths.

When NOT to Use slice

  • Early exit neededKeepIf iterates entire slice; use loop with break for first match
  • Accumulating into maps — No fluent equivalent; use Fold or a loop
  • Performance-critical hot paths — Profile first; each chain operation allocates
  • Single simple operationfor _, u := range users may be clearer than slice.From(users).Each(...)

When Loops Are Necessary

  • Channel consumption: for r := range ch
  • Complex control flow: break, continue, early return
  • Index-dependent logic: comparing adjacent elements, position-aware output

See Also

Documentation

Overview

Package slice provides fluent slice types that can chain functional collection operations.

Mapper[T] is a fluent slice that can chain operations like ToString (map), KeepIf (filter), etc.

MapperTo[T, R] is a fluent slice with one additional method, MapTo, for mapping to a specified type R. If you don't need to map to an arbitrary type, use Mapper instead.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Fold added in v0.6.0

func Fold[T, R any](ts []T, initial R, fn func(R, T) R) R

Fold reduces a slice to a single value by applying fn to each element. It starts with initial and applies fn(accumulator, element) for each element from left to right. Returns initial if the slice is empty.

func Unzip2 added in v0.6.0

func Unzip2[T, A, B any](ts []T, fa func(T) A, fb func(T) B) (Mapper[A], Mapper[B])

Unzip2 extracts two slices from ts in a single pass by applying the extraction functions. This is more efficient than calling two separate mapping operations when you need multiple fields.

func Unzip3 added in v0.6.0

func Unzip3[T, A, B, C any](ts []T, fa func(T) A, fb func(T) B, fc func(T) C) (Mapper[A], Mapper[B], Mapper[C])

Unzip3 extracts three slices from ts in a single pass by applying the extraction functions.

func Unzip4 added in v0.6.0

func Unzip4[T, A, B, C, D any](ts []T, fa func(T) A, fb func(T) B, fc func(T) C, fd func(T) D) (Mapper[A], Mapper[B], Mapper[C], Mapper[D])

Unzip4 extracts four slices from ts in a single pass by applying the extraction functions.

Types

type Any

type Any = Mapper[any]

type Bool

type Bool = Mapper[bool]

type Byte

type Byte = Mapper[byte]

type Error

type Error = Mapper[error]

type Float32

type Float32 = Mapper[float32]

type Float64

type Float64 = Mapper[float64]

type Int

type Int = Mapper[int]

type Mapper

type Mapper[T any] []T

Mapper is a fluent slice usable anywhere a regular slice is, but provides additional fluent fp methods. Its underlying type is []T.

func From

func From[T any](ts []T) Mapper[T]

func (Mapper[T]) Convert

func (ts Mapper[T]) Convert(fn func(T) T) Mapper[T]

Convert returns the result of applying fn to each member of ts.

func (Mapper[T]) Each

func (ts Mapper[T]) Each(fn func(T))

Each applies fn to each member of ts.

func (Mapper[T]) KeepIf

func (ts Mapper[T]) KeepIf(fn func(T) bool) Mapper[T]

KeepIf returns a new slice containing the members of ts for which fn returns true. It is the complement of RemoveIf.

func (Mapper[T]) Len

func (ts Mapper[T]) Len() int

Len returns the length of the slice.

func (Mapper[T]) RemoveIf

func (ts Mapper[T]) RemoveIf(fn func(T) bool) Mapper[T]

RemoveIf returns a new slice containing members for which fn returns false. It is the complement of KeepIf.

func (Mapper[T]) TakeFirst

func (ts Mapper[T]) TakeFirst(n int) Mapper[T]

TakeFirst returns the first n elements of ts.

func (Mapper[T]) ToAny

func (ts Mapper[T]) ToAny(fn func(T) any) Mapper[any]

ToAny returns the result of applying fn to each member of ts.

func (Mapper[T]) ToBool

func (ts Mapper[T]) ToBool(fn func(T) bool) Mapper[bool]

ToBool returns the result of applying fn to each member of ts.

func (Mapper[T]) ToByte

func (ts Mapper[T]) ToByte(fn func(T) byte) Mapper[byte]

ToByte returns the result of applying fn to each member of ts.

func (Mapper[T]) ToError

func (ts Mapper[T]) ToError(fn func(T) error) Mapper[error]

ToError returns the result of applying fn to each member of ts.

func (Mapper[T]) ToFloat32

func (ts Mapper[T]) ToFloat32(fn func(T) float32) Mapper[float32]

ToFloat32 returns the result of applying fn to each member of ts.

func (Mapper[T]) ToFloat64

func (ts Mapper[T]) ToFloat64(fn func(T) float64) Mapper[float64]

ToFloat64 returns the result of applying fn to each member of ts.

func (Mapper[T]) ToInt

func (ts Mapper[T]) ToInt(fn func(T) int) Mapper[int]

ToInt returns the result of applying fn to each member of ts.

func (Mapper[T]) ToInt32 added in v0.8.0

func (ts Mapper[T]) ToInt32(fn func(T) int32) Mapper[int32]

ToInt32 returns the result of applying fn to each member of ts.

func (Mapper[T]) ToInt64 added in v0.8.0

func (ts Mapper[T]) ToInt64(fn func(T) int64) Mapper[int64]

ToInt64 returns the result of applying fn to each member of ts.

func (Mapper[T]) ToRune

func (ts Mapper[T]) ToRune(fn func(T) rune) Mapper[rune]

ToRune returns the result of applying fn to each member of ts.

func (Mapper[T]) ToString

func (ts Mapper[T]) ToString(fn func(T) string) Mapper[string]

ToString returns the result of applying fn to each member of ts.

type MapperTo

type MapperTo[R, T any] []T

MapperTo is a fluent slice with one additional method, MapTo, for mapping to a specified type R. If you don't need to map to an arbitrary type, use Mapper instead.

func MapTo

func MapTo[R, T any](ts []T) MapperTo[R, T]

func (MapperTo[R, T]) Convert

func (ts MapperTo[R, T]) Convert(fn func(T) T) MapperTo[R, T]

Convert returns the result of applying fn to each member of ts.

func (MapperTo[R, T]) Each

func (ts MapperTo[R, T]) Each(fn func(T))

Each applies fn to each member of ts.

func (MapperTo[R, T]) KeepIf

func (ts MapperTo[R, T]) KeepIf(fn func(T) bool) MapperTo[R, T]

KeepIf returns a new slice containing the members of ts for which fn returns true. It is the complement of RemoveIf.

func (MapperTo[T, R]) Len

func (ts MapperTo[T, R]) Len() int

Len returns the length of the slice.

func (MapperTo[R, T]) RemoveIf

func (ts MapperTo[R, T]) RemoveIf(fn func(T) bool) MapperTo[R, T]

RemoveIf returns a new slice containing members for which fn returns false. It is the complement of KeepIf.

func (MapperTo[R, T]) TakeFirst

func (ts MapperTo[R, T]) TakeFirst(n int) MapperTo[R, T]

TakeFirst returns the first n members of ts.

func (MapperTo[R, T]) To

func (ts MapperTo[R, T]) To(fn func(T) R) Mapper[R]

To returns the result of applying fn to each member of ts.

func (MapperTo[R, T]) ToAny

func (ts MapperTo[R, T]) ToAny(fn func(T) any) MapperTo[R, any]

ToAny returns the result of applying fn to each member of ts.

func (MapperTo[R, T]) ToBool

func (ts MapperTo[R, T]) ToBool(fn func(T) bool) MapperTo[R, bool]

ToBool returns the result of applying fn to each member of ts.

func (MapperTo[R, T]) ToByte

func (ts MapperTo[R, T]) ToByte(fn func(T) byte) MapperTo[R, byte]

ToByte returns the result of applying fn to each member of ts.

func (MapperTo[R, T]) ToError

func (ts MapperTo[R, T]) ToError(fn func(T) error) MapperTo[R, error]

ToError returns the result of applying fn to each member of ts.

func (MapperTo[R, T]) ToFloat32

func (ts MapperTo[R, T]) ToFloat32(fn func(T) float32) MapperTo[R, float32]

ToFloat32 returns the result of applying fn to each member of ts.

func (MapperTo[R, T]) ToFloat64

func (ts MapperTo[R, T]) ToFloat64(fn func(T) float64) MapperTo[R, float64]

ToFloat64 returns the result of applying fn to each member of ts.

func (MapperTo[R, T]) ToInt

func (ts MapperTo[R, T]) ToInt(fn func(T) int) MapperTo[R, int]

ToInt returns the result of applying fn to each member of ts.

func (MapperTo[R, T]) ToInt32 added in v0.8.0

func (ts MapperTo[R, T]) ToInt32(fn func(T) int32) MapperTo[R, int32]

ToInt32 returns the result of applying fn to each member of ts.

func (MapperTo[R, T]) ToInt64 added in v0.8.0

func (ts MapperTo[R, T]) ToInt64(fn func(T) int64) MapperTo[R, int64]

ToInt64 returns the result of applying fn to each member of ts.

func (MapperTo[R, T]) ToRune

func (ts MapperTo[R, T]) ToRune(fn func(T) rune) MapperTo[R, rune]

ToRune returns the result of applying fn to each member of ts.

func (MapperTo[R, T]) ToString

func (ts MapperTo[R, T]) ToString(fn func(T) string) MapperTo[R, string]

ToString returns the result of applying fn to each member of ts.

type Rune

type Rune = Mapper[rune]

type String

type String = Mapper[string]

Jump to

Keyboard shortcuts

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