types

package module
v0.0.6 Latest Latest
Warning

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

Go to latest
Published: Apr 26, 2026 License: MIT Imports: 11 Imported by: 8

README

Types

Go Report Card GoDoc codecov

Go implementation for generic types, imitating Ruby types

Data structures

Slice

A slice of comparable type that can hold any value

Example
func ExampleSlice() {
	a := Slice[int]{1, 2, 3, 4, 5, 6}

	// multiply every element by 100
	a = a.Map(func(e int) int {
		return e * 100
	})

	// select any element <= 300
	a = a.KeepIf(func(e int) bool {
		return e <= 300
	})

	fmt.Print(a)

	// Output: [100 200 300]
}
Slice Methods available:
func (a Slice[T]) All(block func(T) bool) bool
func (a Slice[T]) Any(block func(T) bool) bool
func (a Slice[T]) At(index int) *T
func (a Slice[T]) Compact() Slice[T]
func (a Slice[T]) CountBy(block func(T) bool) (count int)
func (a Slice[T]) CountElement(element T) (count int)
func (a Slice[T]) Cycle(count int, block func(T))
func (a Slice[T]) Delete(element T) Slice[T]
func (a Slice[T]) DeleteAt(index int) Slice[T]
func (a Slice[T]) DeleteIf(block func(T) bool) Slice[T]
func (a Slice[T]) Drop(count int) Slice[T]
func (a Slice[T]) DropWhile(predicate func(T) bool) Slice[T]
func (a Slice[T]) Each(block func(T))
func (a Slice[T]) EachIndex(block func(int))
func (a Slice[T]) Fetch(index int, defaultValue T) T
func (a Slice[T]) Fill(element T, start int, length int) Slice[T]
func (a Slice[T]) FillWith(start int, length int, block func(int) T) Slice[T]
func (a Slice[T]) Find(predicate func(T) bool) (T, bool)
func (a Slice[T]) First() *T
func (a Slice[T]) Firsts(count int) Slice[T]
func (a Slice[T]) Include(element T) bool
func (a Slice[T]) Index(element T) int
func (a Slice[T]) IndexBy(block func(T) bool) int
func (a Slice[T]) Insert(index int, elements ...T) Slice[T]
func (a Slice[T]) IsEmpty() bool
func (a Slice[T]) IsEq(other Slice[T]) bool
func (a Slice[T]) KeepIf(block func(T) bool) Slice[T]
func (a Slice[T]) Last() *T
func (a Slice[T]) Lasts(count int) Slice[T]
func (a Slice[T]) Len() int
func (a Slice[T]) Map(block func(T) T) Slice[T]
func (a Slice[T]) Max(block func(T) int) T
func (a Slice[T]) Min(block func(T) int) T
func (a Slice[T]) None(predicate func(T) bool) bool
func (a Slice[T]) Partition(predicate func(T) bool) (Slice[T], Slice[T])
func (a Slice[T]) Pop() (Slice[T], T)
func (a Slice[T]) Push(element T) Slice[T]
func (a Slice[T]) Reduce(block func(T) bool) Slice[T]
func (a Slice[T]) Reverse() Slice[T]
func (a Slice[T]) Rotate(count int) Slice[T]
func (a Slice[T]) Sample() (T, bool)
func (a Slice[T]) SampleN(n int) Slice[T]
func (a Slice[T]) Select(block func(T) bool) Slice[T]
func (a Slice[T]) SelectUntil(block func(T) bool) Slice[T]
func (a Slice[T]) Shift() (T, Slice[T])
func (a Slice[T]) Shuffle() Slice[T]
func (a Slice[T]) TakeWhile(predicate func(T) bool) Slice[T]
func (a Slice[T]) Tally() map[T]int
func (a Slice[T]) Unique() Slice[T]
func (a Slice[T]) Unshift(element T) Slice[T]
func Zip[T, U comparable](a Slice[T], b Slice[U]) [][2]any
func SliceReduce[T comparable, U any](s Slice[T], initial U, fn func(U, T) U) U

Set

An order-preserving set of comparable type that stores unique elements

Example
func ExampleSet() {
	s := NewSet(1, 2, 3, 3, 4, 5)

	// Set automatically deduplicates
	fmt.Println(s.Size()) // 5

	// Add elements
	s.Add(6)
	s.Add(3) // returns false, already exists

	// Set operations
	other := NewSet(4, 5, 6, 7)
	union := s.Union(other)
	intersection := s.Intersection(other)

	// Functional operations
	filtered := s.Filter(func(x int) bool {
		return x > 3
	})

	doubled := SetMap(s, func(x int) int {
		return x * 2
	})

	fmt.Print(filtered)

	// Output: Set{4, 5, 6}
}
Set Methods available:
func NewSet[T comparable](slice ...T) *Set[T]
func (s *Set[T]) Add(item T) bool
func (s *Set[T]) All(predicate func(T) bool) bool
func (s *Set[T]) Any(predicate func(T) bool) bool
func (s *Set[T]) Clear()
func (s *Set[T]) Clone() *Set[T]
func (s *Set[T]) Contains(item T) bool
func (s *Set[T]) Count(predicate func(T) bool) int
func (s *Set[T]) Difference(other *Set[T]) *Set[T]
func (s *Set[T]) Drop(n int) *Set[T]
func (s *Set[T]) Each(fn func(T))
func (s *Set[T]) Equal(other *Set[T]) bool
func (s *Set[T]) Filter(predicate func(T) bool) *Set[T]
func (s *Set[T]) Find(predicate func(T) bool) (T, bool)
func (s *Set[T]) Intersection(other *Set[T]) *Set[T]
func (s *Set[T]) IsDisjoint(other *Set[T]) bool
func (s *Set[T]) IsEmpty() bool
func (s *Set[T]) IsSubset(other *Set[T]) bool
func (s *Set[T]) IsSuperset(other *Set[T]) bool
func (s *Set[T]) None(predicate func(T) bool) bool
func (s *Set[T]) Partition(predicate func(T) bool) (*Set[T], *Set[T])
func (s *Set[T]) Reject(predicate func(T) bool) *Set[T]
func (s *Set[T]) Remove(item T) bool
func (s *Set[T]) Size() int
func (s *Set[T]) String() string
func (s *Set[T]) SymmetricDifference(other *Set[T]) *Set[T]
func (s *Set[T]) Take(n int) *Set[T]
func (s *Set[T]) ToSlice() []T
func (s *Set[T]) Union(other *Set[T]) *Set[T]
func SetMap[T, U comparable](s *Set[T], fn func(T) U) *Set[U]
func SetReduce[T comparable, U any](s *Set[T], initial U, fn func(U, T) U) U

Map

A thread-safe generic wrapper around sync.Map with type-safe key-value operations

Example
func ExampleMap() {
	m := Map[string, int]{}

	// Store values
	m.Store("one", 1)
	m.Store("two", 2)
	m.Store("three", 3)

	// Load values
	if val, ok := m.Load("two"); ok {
		fmt.Println(val) // 2
	}

	// Check if key exists
	if m.Has("one") {
		fmt.Println("one exists")
	}

	// Get all keys and values
	keys := m.Keys()     // []string{"one", "two", "three"}
	values := m.Values() // []int{1, 2, 3}

	// Get size
	size := m.Size() // 3

	// Filter entries
	filtered := m.Filter(func(k string, v int) bool {
		return v > 1 // Keep values greater than 1
	})
	// filtered contains: {"two": 2, "three": 3}

	// Iterate without early termination
	m.ForEach(func(k string, v int) {
		fmt.Printf("%s: %d\n", k, v)
	})

	// LoadOrStore
	actual, loaded := m.LoadOrStore("four", 4)
	fmt.Println(loaded) // false (newly stored)

	// Delete
	m.Delete("one")

	// Clear all entries
	m.Clear()
}
Map Methods available:
// Basic operations
func (m *Map[K, V]) Delete(k K)
func (m *Map[K, V]) Load(k K) (v V, ok bool)
func (m *Map[K, V]) LoadAndDelete(k K) (v V, loaded bool)
func (m *Map[K, V]) LoadOrStore(k K, v V) (actual V, loaded bool)
func (m *Map[K, V]) Store(k K, v V)
func (m *Map[K, V]) Swap(k K, v V) (previous V, loaded bool)

// Iteration
func (m *Map[K, V]) Range(f func(k K, v V) bool)
func (m *Map[K, V]) ForEach(f func(k K, v V))

// Utility methods
func (m *Map[K, V]) Clear()
func (m *Map[K, V]) Has(k K) bool
func (m *Map[K, V]) Keys() []K
func (m *Map[K, V]) Values() []V
func (m *Map[K, V]) Size() int

// Functional operations
func (m *Map[K, V]) Filter(predicate func(k K, v V) bool) *Map[K, V]

Chan

Generic channel utility functions for functional-style channel operations

Example
func ExampleChan() {
	// Create input channel
	input := make(chan int)
	go func() {
		defer close(input)
		for i := 1; i <= 10; i++ {
			input <- i
		}
	}()

	// Map: transform each value
	doubled := ChanMap(input, func(x int) int {
		return x * 2
	})

	// Filter: keep only values > 10
	filtered := ChanFilter(doubled, func(x int) bool {
		return x > 10
	})

	// Each: consume and print
	ChanEach(filtered, func(x int) {
		fmt.Println(x)
	})
	// Output: 12 14 16 18 20
}
Chan Functions available:
func OrderedParallelizeChan[In, Out any](input <-chan In, workers int, process func(<-chan In) <-chan Out) <-chan Out
func ChanMap[In, Out any](input <-chan In, processor func(In) Out) <-chan Out
func ChanFilter[T any](input <-chan T, filter func(T) bool) <-chan T
func ChanEach[T any](input <-chan T, fns ...func(T))

Command

A fluent interface for executing system commands with support for piping, chaining, and custom function transformations.

Features
  • Command Chaining: Chain commands together with Pipe
  • Function Transformations: Inject Go functions into pipelines with PipeFn and CmdFn
  • Sudo Support: Run commands with sudo privileges
  • Interactive Mode: Connect commands directly to terminal for user input
  • Input Redirection: Provide stdin from strings or io.Reader
  • Context Support: Cancel or timeout commands with context
  • Working Directory: Set the directory where commands execute
  • Environment Variables: Configure command environment
  • Exit Code Access: Get command exit codes
  • Retry Logic: Retry failed commands with optional backoff
  • Lazy Execution: Commands execute only when output is requested
  • Idempotent: Multiple calls to output methods return cached results
Example
func ExampleCommand() {
	// Simple command execution
	output := Cmd("echo", "hello world").Stdout()
	fmt.Println(output) // "hello world\n"

	// Piping commands together
	result := Cmd("echo", "apple\nbanana\napricot").
		Pipe("grep", "a").
		Pipe("wc", "-l").
		Stdout()
	fmt.Println(strings.TrimSpace(result)) // "3"

	// Using custom functions in pipelines
	upperResult := Cmd("echo", "hello").
		PipeFn(func(stdin string) (string, string, error) {
			return strings.ToUpper(stdin), "", nil
		}).
		Stdout()
	fmt.Println(upperResult) // "HELLO\n"

	// Input redirection
	grepResult := Cmd("grep", "hello").
		Input("hello world\ngoodbye\nhello again").
		Stdout()
	fmt.Println(grepResult) // "hello world\nhello again\n"

	// Running with sudo (requires authentication)
	err := Cmd("systemctl", "restart", "nginx").Sudo().Error()
	if err != nil {
		// handle error
	}

	// Interactive mode for commands requiring user input
	err = Cmd("vim", "file.txt").Interactive().Error()
	
	// Timeout for long-running commands
	output = Cmd("sleep", "10").WithTimeout(2*time.Second).Stdout()
	// Returns with context deadline exceeded error
	
	// Set working directory
	output = Cmd("ls").Dir("/tmp").Stdout()
	
	// Set environment variables
	output = Cmd("printenv", "MY_VAR").
		Env("MY_VAR", "hello").
		Env("ANOTHER", "world").
		Stdout()
	
	// Get exit code
	cmd := Cmd("false").Run()
	exitCode := cmd.ExitCode() // 1
	
	// Retry with backoff
	output = Cmd("curl", "http://example.com").
		RetryWithBackoff(3, 2*time.Second).
		Stdout()
	
	// Get trimmed output (no trailing whitespace)
	version := Cmd("git", "--version").StdoutTrimmed()
}
Command Functions and Methods
// Creating commands
func Cmd(cmd string, args ...string) *Command
func CmdFn(fn func(stdin string) (stdout, stderr string, err error)) *Command
func Sudo(cmd string, args ...string) *Command

// Chaining and piping
func (c *Command) Pipe(cmd string, args ...string) *Command
func (c *Command) PipeFn(fn func(stdin string) (stdout, stderr string, err error)) *Command

// Configuration
func (c *Command) Interactive() *Command
func (c *Command) Input(input string) *Command
func (c *Command) InputReader(r io.Reader) *Command
func (c *Command) Sudo() *Command
func (c *Command) Dir(path string) *Command
func (c *Command) Env(key, value string) *Command
func (c *Command) EnvMap(env map[string]string) *Command
func (c *Command) ClearEnv() *Command

// Context and timeout
func (c *Command) WithContext(ctx context.Context) *Command
func (c *Command) WithTimeout(duration time.Duration) *Command
func (c *Command) WithDeadline(t time.Time) *Command

// Retry logic
func (c *Command) Retry(attempts int) *Command
func (c *Command) RetryWithBackoff(attempts int, delay time.Duration) *Command

// Execution and output
func (c *Command) Run() *Command
func (c *Command) Stdout() string
func (c *Command) StdoutTrimmed() string
func (c *Command) Stderr() string
func (c *Command) Error() error
func (c *Command) ExitCode() int
func (c *Command) StdoutErr() (string, error)
func (c *Command) StderrErr() (string, error)
func (c *Command) StdoutStderr() string

// Utility
func (c *Command) String() string

Documentation

Overview

Package types provides a generic data types similar to that of Ruby

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func ChanEach added in v0.0.6

func ChanEach[T any](input <-chan T, fns ...func(T))

ChanEach consumes all items from the input channel, and passes them to the provided functions for processing. It does not return any output channel.

func ChanFilter added in v0.0.6

func ChanFilter[T any](input <-chan T, filter func(T) bool) <-chan T

ChanFilter takes a channel of inputs and a filter function, returning an output channel with only the items that pass the filter.

func ChanMap added in v0.0.6

func ChanMap[In, Out any](input <-chan In, processor func(In) Out) <-chan Out

ChanMap takes a channel of inputs and a processor function that converts input to output, and returns an output channel with processed results.

func Flatten added in v0.0.6

func Flatten[T any](a [][]T) []T

Flatten converts a slice of slices into a single-level slice by concatenating all nested slices. This is inspired by Ruby's Array#flatten method (depth=1). Example: Flatten(Slice[Slice[int]]{{1, 2}, {3, 4}, {5}}) returns Slice[int]{1, 2, 3, 4, 5}

Example
nested := [][]int{
	{1, 2, 3},
	{4, 5},
	{6, 7, 8, 9},
}

flat := Flatten(nested)
fmt.Println(flat)
Output:
[1 2 3 4 5 6 7 8 9]
Example (Strings)
words := [][]string{
	{"hello", "world"},
	{"foo", "bar"},
	{"baz"},
}

result := Flatten(words)
fmt.Println(result)
Output:
[hello world foo bar baz]
Example (WithEmptySlices)
nested := [][]int{
	{1, 2},
	{},
	{3, 4},
	{},
	{5},
}

flat := Flatten(nested)
fmt.Println(flat)
Output:
[1 2 3 4 5]

func OrderedParallelizeChan added in v0.0.6

func OrderedParallelizeChan[In, Out any](input <-chan In, workers int, process func(<-chan In) <-chan Out) <-chan Out

OrderedParallelizeChan splits input channel to multiple worker channels, processes them in parallel, then merges results back whilst preserving the original order of items.

func SetReduce added in v0.0.6

func SetReduce[T comparable, U any](s *Set[T], initial U, fn func(U, T) U) U

SetReduce applies a reduction function to all elements in the set, starting with an initial value. The reduction function takes the accumulated value and the current element, returning the new accumulated value.

func SliceReduce added in v0.0.6

func SliceReduce[T comparable, U any](s Slice[T], initial U, fn func(U, T) U) U

SliceReduce applies a function against an accumulator and each element in the slice

func SliceSum added in v0.0.6

func SliceSum[T Number](s Slice[T]) T

SliceSum returns the sum of all elements in the slice. Works with any numeric type (int, float64, etc.). Returns the zero value for an empty slice.

Example
numbers := Slice[int]{1, 2, 3, 4, 5}
total := SliceSum(numbers)
fmt.Println(total)
Output:
15
Example (Floats)
prices := Slice[float64]{19.99, 29.99, 9.99}
total := SliceSum(prices)
fmt.Printf("%.2f\n", total)
Output:
59.97

func Zip added in v0.0.6

func Zip[T, U comparable](a Slice[T], b Slice[U]) [][2]any

Zip combines this slice with another slice element-wise, creating pairs. Returns a slice of pairs (2-element arrays) where each pair contains one element from this slice and one from the other slice at the same index. The resulting slice will have the length of the shorter input slice. Inspired by Ruby's Array#zip method. Example: Slice[int]{1, 2, 3}.Zip(Slice[string]{"a", "b"}) returns [[1,"a"], [2,"b"]]

Example
// Zip two slices of different types
numbers := Slice[int]{1, 2, 3, 4}
letters := Slice[string]{"a", "b", "c"}

// Zip combines them element-wise
// Result length is determined by the shorter slice
pairs := Zip(numbers, letters)

for _, pair := range pairs {
	fmt.Printf("(%v, %v) ", pair[0], pair[1])
}
Output:
(1, a) (2, b) (3, c)
Example (SameTypes)
// Zip works with slices of the same type too
first := Slice[int]{1, 2, 3}
second := Slice[int]{10, 20, 30}

pairs := Zip(first, second)

for _, pair := range pairs {
	sum := pair[0].(int) + pair[1].(int)
	fmt.Printf("%v+%v=%v ", pair[0], pair[1], sum)
}
Output:
1+10=11 2+20=22 3+30=33

Types

type Command added in v0.0.6

type Command struct {
	// contains filtered or unexported fields
}

Command represents a system command that can be chained and piped together. Commands are executed lazily - they only run when an output method is called (Stdout, Stderr, Error, Run, etc.).

Command supports:

  • Command chaining via Pipe with efficient streaming (no buffering of large outputs)
  • Function transformations via PipeFn
  • Sudo execution
  • Interactive mode for terminal input/output
  • Input redirection

Commands are idempotent - calling output methods multiple times executes the command only once and returns cached results.

Piped commands use streaming I/O, connecting stdout directly to stdin without buffering the entire output in memory. This makes pipelines memory-efficient even with large data.

func Cmd added in v0.0.6

func Cmd(cmd string, args ...string) *Command

Cmd creates a new Command with the given command name and arguments. The command will not execute until an output method is called.

Example:

cmd := types.Cmd("echo", "hello", "world")
output := cmd.Stdout() // "hello world\n"
Example
output := Cmd("echo", "hello world").Stdout()
fmt.Print(output)
Output:
hello world
Example (Input)
result := Cmd("grep", "hello").
	Input("hello world\ngoodbye\nhello again").
	Stdout()
fmt.Print(result)
Output:
hello world
hello again
Example (Pipe)
result := Cmd("echo", "apple\nbanana\napricot").
	Pipe("grep", "a").
	Stdout()
fmt.Print(result)
Output:
apple
banana
apricot

func CmdFn added in v0.0.6

func CmdFn(fn func(stdin string) (stdout, stderr string, outErr error)) *Command

CmdFn creates a new Command from a function that transforms stdin to stdout/stderr. This allows inserting custom Go functions into command pipelines.

The function receives stdin as a string and returns stdout, stderr, and an error.

Example:

upperCase := types.CmdFn(func(stdin string) (string, string, error) {
	return strings.ToUpper(stdin), "", nil
})
result := types.Cmd("echo", "hello").PipeFn(upperCase.cmdFn).Stdout() // "HELLO\n"
Example
upperCase := CmdFn(func(stdin string) (string, string, error) {
	return strings.ToUpper(stdin), "", nil
})

result := upperCase.Input("hello world").Stdout()
fmt.Print(result)
Output:
HELLO WORLD

func Sudo added in v0.0.6

func Sudo(cmd string, args ...string) *Command

Sudo creates a new Command with sudo privileges. This is a convenience function equivalent to Cmd(cmd, args...).Sudo().

Example:

result := types.Sudo("systemctl", "restart", "nginx").Stdout()

func (*Command) ClearEnv added in v0.0.6

func (c *Command) ClearEnv() *Command

ClearEnv clears all inherited environment variables. Only variables set via Env() or EnvMap() will be available.

Example:

output := types.Cmd("env").ClearEnv().Env("ONLY_VAR", "value").Stdout()

func (*Command) Dir added in v0.0.6

func (c *Command) Dir(path string) *Command

Dir sets the working directory for the command. If not set, the command runs in the current working directory.

Example:

output := types.Cmd("ls").Dir("/tmp").Stdout()
Example
// Run command in a specific directory
output := Cmd("pwd").Dir("/tmp").Stdout()
fmt.Print(strings.TrimSpace(output))
Output:
/tmp

func (*Command) Env added in v0.0.6

func (c *Command) Env(key, value string) *Command

Env sets a single environment variable for the command. Can be called multiple times to set multiple variables.

Example:

output := types.Cmd("printenv", "MY_VAR").Env("MY_VAR", "hello").Stdout()
Example
// Set environment variables for the command
output := Cmd("sh", "-c", "echo $MY_VAR").Env("MY_VAR", "hello").Stdout()
fmt.Print(output)
Output:
hello

func (*Command) EnvMap added in v0.0.6

func (c *Command) EnvMap(env map[string]string) *Command

EnvMap sets multiple environment variables from a map. Existing environment variables are preserved unless overridden.

Example:

envVars := map[string]string{"PATH": "/usr/bin", "HOME": "/tmp"}
output := types.Cmd("env").EnvMap(envVars).Stdout()

func (*Command) Error added in v0.0.6

func (c *Command) Error() error

Error executes the command and returns any error that occurred. Returns nil if the command executed successfully.

Example:

if err := types.Cmd("false").Error(); err != nil {
	// handle error
}

func (*Command) ExitCode added in v0.0.6

func (c *Command) ExitCode() int

ExitCode returns the exit code of the command after execution. Returns 0 if the command hasn't been executed yet or succeeded. For non-zero exit codes, also check Error() for the error message.

Example:

cmd := types.Cmd("false").Run()
if cmd.ExitCode() != 0 {
	// handle non-zero exit
}
Example
// Get the exit code of a failed command
cmd := Cmd("sh", "-c", "exit 42").Run()
fmt.Printf("Exit code: %d", cmd.ExitCode())
Output:
Exit code: 42

func (*Command) Input added in v0.0.6

func (c *Command) Input(input string) *Command

Input sets the stdin for the command from a string. This is useful for providing input to commands that read from stdin.

Example:

result := types.Cmd("grep", "hello").
	Input("hello world\ngoodbye\nhello again").
	Stdout() // "hello world\nhello again\n"

func (*Command) InputReader added in v0.0.6

func (c *Command) InputReader(r io.Reader) *Command

InputReader sets the stdin for the command from an io.Reader. This is useful for streaming input from files or other sources.

Example:

file, _ := os.Open("input.txt")
result := types.Cmd("wc", "-l").InputReader(file).Stdout()

func (*Command) Interactive added in v0.0.6

func (c *Command) Interactive() *Command

Interactive sets the command to run in interactive mode. In interactive mode, stdin/stdout/stderr are connected directly to the terminal instead of being captured. This is useful for commands that require user input or display progress.

Example:

err := types.Cmd("vim", "file.txt").Interactive().Error()

func (*Command) Pipe added in v0.0.6

func (c *Command) Pipe(cmd string, args ...string) *Command

Pipe chains another command to receive this command's stdout as stdin. This creates a pipeline similar to shell pipes (|).

Commands are connected via streaming pipes, allowing efficient processing of large outputs without buffering everything in memory. The previous command's stdout is directly connected to the next command's stdin.

Errors from earlier commands in the pipeline prevent later commands from executing.

Example:

result := types.Cmd("echo", "apple\nbanana\napricot").
	Pipe("grep", "a").
	Pipe("wc", "-l").
	Stdout() // "3\n"
Example
result := Cmd("echo", "one\ntwo\nthree").
	Pipe("wc", "-l").
	Stdout()
fmt.Print(strings.TrimSpace(result))
Output:
3

func (*Command) PipeFn added in v0.0.6

func (c *Command) PipeFn(fn func(stdin string) (stdout, stderr string, outErr error)) *Command

PipeFn chains a function to receive this command's stdout as stdin. This allows inserting custom transformations into command pipelines.

Example:

result := types.Cmd("echo", "hello").
	PipeFn(func(stdin string) (string, string, error) {
		return strings.ToUpper(stdin), "", nil
	}).
	Stdout() // "HELLO\n"
Example
result := Cmd("echo", "hello").
	PipeFn(func(stdin string) (string, string, error) {
		return strings.ToUpper(stdin), "", nil
	}).
	Stdout()
fmt.Print(result)
Output:
HELLO

func (*Command) Retry added in v0.0.6

func (c *Command) Retry(attempts int) *Command

Retry sets the number of retry attempts for the command. If the command fails, it will be retried up to the specified number of times. Use RetryWithBackoff for delays between retries.

Example:

output := types.Cmd("curl", "http://example.com").Retry(3).Stdout()

func (*Command) RetryWithBackoff added in v0.0.6

func (c *Command) RetryWithBackoff(attempts int, delay time.Duration) *Command

RetryWithBackoff sets retry attempts with a delay between each retry. The delay is constant for all retries.

Example:

output := types.Cmd("curl", "http://example.com").
	RetryWithBackoff(3, 2*time.Second).
	Stdout()

func (*Command) Run added in v0.0.6

func (c *Command) Run() *Command

Run executes the command and returns the Command for chaining. This is useful when you want to ensure execution but don't need the output.

Example:

types.Cmd("mkdir", "-p", "/tmp/test").Run()

func (*Command) Stderr added in v0.0.6

func (c *Command) Stderr() string

Stderr executes the command and returns its stderr. Multiple calls return the cached result without re-executing.

Example:

errMsg := types.Cmd("ls", "/nonexistent").Stderr()

func (*Command) StderrErr added in v0.0.6

func (c *Command) StderrErr() (string, error)

StderrErr executes the command and returns both stderr and any error.

Example:

errOutput, err := types.Cmd("ls", "/nonexistent").StderrErr()

func (*Command) Stdout added in v0.0.6

func (c *Command) Stdout() string

Stdout executes the command and returns its stdout. Multiple calls return the cached result without re-executing.

Example:

output := types.Cmd("echo", "hello").Stdout() // "hello\n"

func (*Command) StdoutErr added in v0.0.6

func (c *Command) StdoutErr() (string, error)

StdoutErr executes the command and returns both stdout and any error. This is useful when you need both the output and error information.

Example:

output, err := types.Cmd("ls", "/nonexistent").StdoutErr()
Example
output, err := Cmd("echo", "success").StdoutErr()
fmt.Printf("Output: %s, Error: %v", strings.TrimSpace(output), err)
Output:
Output: success, Error: <nil>

func (*Command) StdoutStderr added in v0.0.6

func (c *Command) StdoutStderr() string

StdoutStderr executes the command and returns both stdout and stderr concatenated. This is useful when you need all output regardless of which stream it came from.

Example:

allOutput := types.Cmd("ls", "/tmp", "/nonexistent").StdoutStderr()

func (*Command) StdoutTrimmed added in v0.0.6

func (c *Command) StdoutTrimmed() string

StdoutTrimmed executes the command and returns stdout with leading/trailing whitespace removed. This is useful for commands that output single values with newlines.

Example:

version := types.Cmd("git", "--version").StdoutTrimmed()
// "git version 2.39.0" (without trailing newline)
Example
// Get stdout without trailing newline
version := Cmd("echo", "v1.2.3").StdoutTrimmed()
fmt.Printf("Version: %s", version)
Output:
Version: v1.2.3

func (*Command) String added in v0.0.6

func (c *Command) String() string

String implements fmt.Stringer and returns a string representation of the command. This shows the command that will be executed, including arguments.

Example:

cmd := types.Cmd("echo", "hello", "world")
fmt.Println(cmd.String()) // "echo hello world"
Example
// Get string representation of a command
cmd := Cmd("git", "commit", "-m", "message")
fmt.Println(cmd.String())
Output:
git commit -m message

func (*Command) Sudo added in v0.0.6

func (c *Command) Sudo() *Command

Sudo sets the command to run with sudo privileges. If sudo authentication is required, the user will be prompted interactively.

Example:

err := types.Cmd("systemctl", "restart", "nginx").Sudo().Error()

func (*Command) WithContext added in v0.0.6

func (c *Command) WithContext(ctx context.Context) *Command

WithContext sets the context for the command. The context can be used for cancellation or timeout.

Example:

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
output := types.Cmd("sleep", "10").WithContext(ctx).Stdout() // cancelled after 5s

func (*Command) WithDeadline added in v0.0.6

func (c *Command) WithDeadline(t time.Time) *Command

WithDeadline sets an absolute deadline for the command using a context with deadline. This is a convenience wrapper around WithContext.

Example:

deadline := time.Now().Add(5*time.Second)
output := types.Cmd("sleep", "10").WithDeadline(deadline).Stdout() // cancelled at deadline

func (*Command) WithTimeout added in v0.0.6

func (c *Command) WithTimeout(duration time.Duration) *Command

WithTimeout sets a timeout for the command using a context with deadline. This is a convenience wrapper around WithContext.

Example:

output := types.Cmd("sleep", "10").WithTimeout(5*time.Second).Stdout() // cancelled after 5s
Example
// Command that completes within timeout
output := Cmd("echo", "hello").WithTimeout(5 * time.Second).Stdout()
fmt.Print(output)
Output:
hello

type Map added in v0.0.4

type Map[K comparable, V any] struct {
	// contains filtered or unexported fields
}

Map is a wrapper for sync.Map with same methods (except for CompareAnd*) Check: https://pkg.go.dev/sync#Map

func NewMapFrom added in v0.0.6

func NewMapFrom[K comparable, V any](m map[K]V) *Map[K, V]

NewMapFrom creates a new Map initialized with entries from a regular Go map. This provides a convenient way to convert from map[K]V to *Map[K, V].

func (*Map[K, V]) All added in v0.0.6

func (m *Map[K, V]) All(predicate func(k K, v V) bool) bool

All returns true if the predicate returns true for all entries in the map. Returns true for empty maps.

func (*Map[K, V]) Any added in v0.0.6

func (m *Map[K, V]) Any(predicate func(k K, v V) bool) bool

Any returns true if the predicate returns true for any entry in the map. Returns false for empty maps.

func (*Map[K, V]) Clear added in v0.0.6

func (m *Map[K, V]) Clear()

Clear removes all entries from the map.

func (*Map[K, V]) Clone added in v0.0.6

func (m *Map[K, V]) Clone() *Map[K, V]

Clone creates and returns a shallow copy of the map. All key-value pairs from the original map are copied to the new map. Changes to the cloned map will not affect the original map and vice versa.

Example
// Create original map with some entries
original := &Map[string, int]{}
original.Store("apples", 5)
original.Store("bananas", 3)
original.Store("oranges", 7)

// Clone the map
clone := original.Clone()

// Modify the clone
clone.Store("apples", 10) // Update existing
clone.Store("grapes", 15) // Add new entry
clone.Delete("bananas")   // Remove entry

// Original remains unchanged
apples, _ := original.Load("apples")
fmt.Println("Original apples:", apples)
fmt.Println("Original has bananas:", original.Has("bananas"))
fmt.Println("Original has grapes:", original.Has("grapes"))

// Clone has the modifications
cApples, _ := clone.Load("apples")
fmt.Println("Clone apples:", cApples)
fmt.Println("Clone has bananas:", clone.Has("bananas"))
fmt.Println("Clone has grapes:", clone.Has("grapes"))
Output:
Original apples: 5
Original has bananas: true
Original has grapes: false
Clone apples: 10
Clone has bananas: false
Clone has grapes: true

func (*Map[K, V]) Delete added in v0.0.4

func (m *Map[K, V]) Delete(k K)

Delete see sync.Map#Delete

func (*Map[K, V]) Entries added in v0.0.6

func (m *Map[K, V]) Entries() map[K]V

Entries returns a regular Go map containing all key-value pairs from the Map. This provides a convenient way to convert from *Map[K, V] to map[K]V. The order of entries is not guaranteed.

func (*Map[K, V]) Filter added in v0.0.6

func (m *Map[K, V]) Filter(predicate func(k K, v V) bool) *Map[K, V]

Filter returns a new Map containing only the entries that satisfy the predicate.

func (*Map[K, V]) ForEach added in v0.0.6

func (m *Map[K, V]) ForEach(f func(k K, v V))

ForEach iterates over all entries in the map, calling the provided function for each key-value pair. Unlike Range, this does not support early termination.

func (*Map[K, V]) Has added in v0.0.6

func (m *Map[K, V]) Has(k K) bool

Has checks if a key exists in the map. This is a convenience method equivalent to checking the ok return value of Load.

func (*Map[K, V]) Keys added in v0.0.6

func (m *Map[K, V]) Keys() []K

Keys returns a slice containing all keys in the map. The order of keys is not guaranteed.

func (*Map[K, V]) Load added in v0.0.4

func (m *Map[K, V]) Load(k K) (v V, ok bool)

func (*Map[K, V]) LoadAndDelete added in v0.0.4

func (m *Map[K, V]) LoadAndDelete(k K) (v V, loaded bool)

LoadAndDelete see sync.Map#LoadAndDelete

func (*Map[K, V]) LoadOrStore added in v0.0.4

func (m *Map[K, V]) LoadOrStore(k K, v V) (actual V, loaded bool)

LoadOrStore see sync.Map#LoadOrStore

func (*Map[K, V]) Merge added in v0.0.6

func (m *Map[K, V]) Merge(other *Map[K, V]) *Map[K, V]

Merge returns a new Map combining entries from both maps. If a key exists in both maps, the value from the other map takes precedence. This is inspired by Ruby's Hash#merge method.

Example
package main

import (
	"fmt"

	"github.com/emad-elsaid/types"
)

func main() {
	// Create first map with default settings
	defaults := types.Map[string, string]{}
	defaults.Store("host", "localhost")
	defaults.Store("port", "8080")
	defaults.Store("timeout", "30")

	// Create second map with user overrides
	overrides := types.Map[string, string]{}
	overrides.Store("port", "3000")
	overrides.Store("debug", "true")

	// Merge: overrides take precedence over defaults
	config := defaults.Merge(&overrides)

	// Print configuration values
	if v, ok := config.Load("host"); ok {
		fmt.Println("host:", v)
	}
	if v, ok := config.Load("port"); ok {
		fmt.Println("port:", v)
	}
	if v, ok := config.Load("timeout"); ok {
		fmt.Println("timeout:", v)
	}
	if v, ok := config.Load("debug"); ok {
		fmt.Println("debug:", v)
	}

}
Output:
host: localhost
port: 3000
timeout: 30
debug: true

func (*Map[K, V]) None added in v0.0.6

func (m *Map[K, V]) None(predicate func(k K, v V) bool) bool

None returns true if no entries in the map satisfy the predicate. Returns true for empty maps.

func (*Map[K, V]) Partition added in v0.0.6

func (m *Map[K, V]) Partition(predicate func(k K, v V) bool) (*Map[K, V], *Map[K, V])

Partition divides the map into two new maps based on the predicate function. Returns two maps: the first contains entries that satisfy the predicate, the second contains entries that do not satisfy the predicate. This is inspired by Ruby's Hash#partition method.

func (*Map[K, V]) Range added in v0.0.4

func (m *Map[K, V]) Range(f func(k K, v V) bool)

Range see sync.Map#Range

func (*Map[K, V]) Size added in v0.0.6

func (m *Map[K, V]) Size() int

Size returns the number of entries in the map. Note: This operation requires iterating through all entries.

func (*Map[K, V]) Store added in v0.0.4

func (m *Map[K, V]) Store(k K, v V)

func (*Map[K, V]) Swap added in v0.0.4

func (m *Map[K, V]) Swap(k K, v V) (previous V, loaded bool)

Swap see sync.Map#Swap

func (*Map[K, V]) Transform added in v0.0.6

func (m *Map[K, V]) Transform(transformer func(k K, v V) V) *Map[K, V]

Transform returns a new Map with transformed values while preserving keys. This is useful for mapping operations on map values while keeping the same key structure.

func (*Map[K, V]) Values added in v0.0.6

func (m *Map[K, V]) Values() []V

Values returns a slice containing all values in the map. The order of values is not guaranteed.

type Number added in v0.0.6

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

Number is a constraint that permits any numeric type.

type Set added in v0.0.5

type Set[T comparable] struct {
	// contains filtered or unexported fields
}

Set represents a generic set data structure that stores unique elements of type T. T must be comparable to be used as map keys.

func NewSet added in v0.0.5

func NewSet[T comparable](slice ...T) *Set[T]

NewSet creates and returns a new Set initialized with elements from the given slice. Duplicate elements in the slice will be automatically deduplicated.

func SetMap added in v0.0.5

func SetMap[T, U comparable](s *Set[T], fn func(T) U) *Set[U]

SetMap applies a transformation function to each element and returns a new set with the results. The transformation function must return a comparable type.

func (*Set[T]) Add added in v0.0.5

func (s *Set[T]) Add(item T) bool

Add inserts an element into the set. Returns true if the element was added (wasn't already present), false otherwise.

func (*Set[T]) All added in v0.0.5

func (s *Set[T]) All(predicate func(T) bool) bool

All returns true if all elements in the set satisfy the predicate function. Returns true for empty sets.

func (*Set[T]) Any added in v0.0.5

func (s *Set[T]) Any(predicate func(T) bool) bool

Any returns true if at least one element in the set satisfies the predicate function. Returns false for empty sets.

func (*Set[T]) Clear added in v0.0.5

func (s *Set[T]) Clear()

Clear removes all elements from the set.

func (*Set[T]) Clone added in v0.0.5

func (s *Set[T]) Clone() *Set[T]

Clone creates and returns a shallow copy of the set.

func (*Set[T]) Contains added in v0.0.5

func (s *Set[T]) Contains(item T) bool

Contains checks if an element exists in the set. Returns true if the element is present, false otherwise.

func (*Set[T]) Count added in v0.0.5

func (s *Set[T]) Count(predicate func(T) bool) int

Count returns the number of elements that satisfy the predicate function.

func (*Set[T]) Difference added in v0.0.5

func (s *Set[T]) Difference(other *Set[T]) *Set[T]

Difference returns a new set containing elements that are in this set but not in the other set in the order they were added to the first set.

func (*Set[T]) Drop added in v0.0.5

func (s *Set[T]) Drop(n int) *Set[T]

Drop returns a new set with the first n elements removed in the order they were added.

func (*Set[T]) Each added in v0.0.5

func (s *Set[T]) Each(fn func(T))

Each iterates over all elements in the set in insertion order and calls the provided function for each element.

func (*Set[T]) Equal added in v0.0.5

func (s *Set[T]) Equal(other *Set[T]) bool

Equal returns true if this set contains exactly the same elements as the other set.

func (*Set[T]) Filter added in v0.0.5

func (s *Set[T]) Filter(predicate func(T) bool) *Set[T]

Filter returns a new set containing only elements that satisfy the predicate function.

func (*Set[T]) Find added in v0.0.5

func (s *Set[T]) Find(predicate func(T) bool) (T, bool)

Find returns the first element that satisfies the predicate function and true. If no element satisfies the predicate, it returns the zero value of T and false.

func (*Set[T]) Intersection added in v0.0.5

func (s *Set[T]) Intersection(other *Set[T]) *Set[T]

Intersection returns a new set containing only elements that are in both this set and the other set in the order they were added to the first set.

func (*Set[T]) IsDisjoint added in v0.0.5

func (s *Set[T]) IsDisjoint(other *Set[T]) bool

IsDisjoint returns true if this set has no elements in common with the other set.

func (*Set[T]) IsEmpty added in v0.0.5

func (s *Set[T]) IsEmpty() bool

IsEmpty returns true if the set contains no elements, false otherwise.

func (*Set[T]) IsSubset added in v0.0.5

func (s *Set[T]) IsSubset(other *Set[T]) bool

IsSubset returns true if this set is a subset of the other set (all elements of this set are in the other set).

func (*Set[T]) IsSuperset added in v0.0.5

func (s *Set[T]) IsSuperset(other *Set[T]) bool

IsSuperset returns true if this set is a superset of the other set (all elements of the other set are in this set).

func (*Set[T]) None added in v0.0.5

func (s *Set[T]) None(predicate func(T) bool) bool

None returns true if no elements in the set satisfy the predicate function. Returns true for empty sets.

func (*Set[T]) Partition added in v0.0.5

func (s *Set[T]) Partition(predicate func(T) bool) (*Set[T], *Set[T])

Partition divides the set into two new sets based on the predicate function. Returns two sets: the first contains elements that satisfy the predicate, the second contains elements that do not satisfy the predicate.

func (*Set[T]) Reject added in v0.0.5

func (s *Set[T]) Reject(predicate func(T) bool) *Set[T]

Reject returns a new set containing only elements that do not satisfy the predicate function. This is the opposite of Filter.

func (*Set[T]) Remove added in v0.0.5

func (s *Set[T]) Remove(item T) bool

Remove deletes an element from the set. Returns true if the element was removed (was present), false otherwise.

func (*Set[T]) Size added in v0.0.5

func (s *Set[T]) Size() int

Size returns the number of elements in the set.

func (*Set[T]) String added in v0.0.5

func (s *Set[T]) String() string

String returns a string representation of the set.

func (*Set[T]) SymmetricDifference added in v0.0.5

func (s *Set[T]) SymmetricDifference(other *Set[T]) *Set[T]

SymmetricDifference returns a new set containing elements that are in either this set or the other set, but not in both.

func (*Set[T]) Take added in v0.0.5

func (s *Set[T]) Take(n int) *Set[T]

Take returns a new set containing up to n elements from this set in the order they were added.

func (*Set[T]) ToSlice added in v0.0.5

func (s *Set[T]) ToSlice() []T

ToSlice returns a copy of the slice containing all elements in the set in the order they were added. The returned slice is a copy, so modifying it will not affect the set.

func (*Set[T]) Union added in v0.0.5

func (s *Set[T]) Union(other *Set[T]) *Set[T]

Union returns a new set containing all elements that are in either this set or the other set.

type Slice

type Slice[T comparable] []T

Slice is an alias for a slice of variables that vary in types Slice can hold any comparable data type

Example
a := Slice[int]{1, 2, 3, 4, 5, 6}

// multiply every element by 100
a = a.Map(func(e int) int {
	return e * 100
})

// select any element <= 300
a = a.KeepIf(func(e int) bool {
	return e <= 300
})

fmt.Print(a)
Output:
[100 200 300]

func (Slice[T]) All

func (a Slice[T]) All(block func(T) bool) bool

All returns true if "block" returned true for all elements in Slice and false otherwise

func (Slice[T]) Any

func (a Slice[T]) Any(block func(T) bool) bool

Any returns true if "block" returned true for any of the Slice elements and false otherwise

func (Slice[T]) At

func (a Slice[T]) At(index int) *T

At returns element by index, a negative index counts from the end of the Slice if index is out of range it returns nil

func (Slice[T]) ChunkWhile added in v0.0.6

func (a Slice[T]) ChunkWhile(predicate func(T, T) bool) []Slice[T]

ChunkWhile groups consecutive elements where the predicate returns true for each pair. The predicate receives two consecutive elements (current, next) and groups continue while it returns true. Returns a slice of slices, each representing a consecutive group. This is inspired by Ruby's Array#chunk_while method. Example: Slice[int]{1, 2, 4, 5, 7, 9}.ChunkWhile(func(a, b int) bool { return b - a == 1 })

returns []Slice[int]{{1, 2}, {4, 5}, {7}, {9}}
Example
package main

import (
	"fmt"

	"github.com/emad-elsaid/types"
)

func main() {
	// Group consecutive numbers
	numbers := types.Slice[int]{1, 2, 4, 5, 7, 9}
	chunks := numbers.ChunkWhile(func(a, b int) bool {
		return b-a == 1
	})
	fmt.Println(chunks)

}
Output:
[[1 2] [4 5] [7] [9]]
Example (Strings)
package main

import (
	"fmt"

	"github.com/emad-elsaid/types"
)

func main() {
	// Group strings by same length
	words := types.Slice[string]{"a", "b", "cc", "dd", "eee", "f"}
	chunks := words.ChunkWhile(func(a, b string) bool {
		return len(a) == len(b)
	})
	fmt.Println(chunks)

}
Output:
[[a b] [cc dd] [eee] [f]]

func (Slice[T]) Compact added in v0.0.6

func (a Slice[T]) Compact() Slice[T]

Compact returns a new slice with all zero values removed. For comparable types, zero values are: 0 for numbers, "" for strings, false for bools, nil for pointers. This is inspired by Ruby's Array#compact method.

func (Slice[T]) CountBy

func (a Slice[T]) CountBy(block func(T) bool) (count int)

CountBy returns number of elements which "block" returns true for

func (Slice[T]) CountElement

func (a Slice[T]) CountElement(element T) (count int)

CountElement returns number of elements equal to "element" in Slice

func (Slice[T]) Cycle

func (a Slice[T]) Cycle(count int, block func(T))

Cycle will cycle through Slice elements "count" times passing each element to "block" function

func (Slice[T]) Delete

func (a Slice[T]) Delete(element T) Slice[T]

Delete will remove all elements that are equal to the passed element

func (Slice[T]) DeleteAt

func (a Slice[T]) DeleteAt(index int) Slice[T]

DeleteAt will delete an element by index If index is out of bounds (negative or >= length), returns original slice unchanged

func (Slice[T]) DeleteIf

func (a Slice[T]) DeleteIf(block func(T) bool) Slice[T]

DeleteIf will delete all elements which "block" returns true for

func (Slice[T]) Drop

func (a Slice[T]) Drop(count int) Slice[T]

Drop will return an array without the first "count" elements from the beginning

func (Slice[T]) DropWhile added in v0.0.6

func (a Slice[T]) DropWhile(predicate func(T) bool) Slice[T]

DropWhile returns a new slice with elements dropped from the start while the predicate returns true. Returns the remaining elements starting from the first element where predicate returns false.

func (Slice[T]) Duplicates added in v0.0.6

func (a Slice[T]) Duplicates() Slice[T]

Duplicates returns a new slice containing elements that appear more than once in the original slice. Each duplicate element appears only once in the result. The order is based on first appearance. Example: Slice[int]{1, 2, 2, 3, 1, 4}.Duplicates() returns Slice[int]{1, 2}

func (Slice[T]) Each

func (a Slice[T]) Each(block func(T))

Each will execute "block" for each element in array

func (Slice[T]) EachIndex

func (a Slice[T]) EachIndex(block func(int))

EachIndex will execute "block" for each element index in array

func (Slice[T]) Fetch

func (a Slice[T]) Fetch(index int, defaultValue T) T

Fetch will return the element in "index", if it doesn't exist it returns the passed "defaultValue"

func (Slice[T]) Fill

func (a Slice[T]) Fill(element T, start int, length int) Slice[T]

Fill will replace elements inplace starting from "start" counting "length" elements with the passed "element" parameter, will return same array object

func (Slice[T]) FillWith

func (a Slice[T]) FillWith(start int, length int, block func(int) T) Slice[T]

FillWith will replace elements from start counting "length" items, passing every index to block and replacing the element inplace with the return value

func (Slice[T]) Find added in v0.0.6

func (a Slice[T]) Find(predicate func(T) bool) (T, bool)

Find returns the first element that satisfies the predicate function and true. If no element satisfies the predicate, it returns the zero value of T and false.

func (Slice[T]) First

func (a Slice[T]) First() *T

First returns first element of array

func (Slice[T]) Firsts

func (a Slice[T]) Firsts(count int) Slice[T]

Firsts will return an array holding the first "count" elements of the array

func (Slice[T]) Include

func (a Slice[T]) Include(element T) bool

Include will return true if element found in the array

func (Slice[T]) Index

func (a Slice[T]) Index(element T) int

Index returns the index of the first element in array that is equal to "element", returns -1 if the elements if not found

func (Slice[T]) IndexBy

func (a Slice[T]) IndexBy(block func(T) bool) int

IndexBy returns first element that block returns true for, -1 otherwise

func (Slice[T]) Insert

func (a Slice[T]) Insert(index int, elements ...T) Slice[T]

Insert will insert a set of elements in the index and will return a new array

func (Slice[T]) IsEmpty

func (a Slice[T]) IsEmpty() bool

IsEmpty will return true of array empty, false otherwise

func (Slice[T]) IsEq

func (a Slice[T]) IsEq(other Slice[T]) bool

IsEq returns true if array the "other" array

func (Slice[T]) KeepIf

func (a Slice[T]) KeepIf(block func(T) bool) Slice[T]

KeepIf will return an array contains all elements where "block" returned true for them

func (Slice[T]) Last

func (a Slice[T]) Last() *T

Last returns last element of array

func (Slice[T]) Lasts

func (a Slice[T]) Lasts(count int) Slice[T]

Lasts will return an array holding the lasts "count" elements of the array

func (Slice[T]) Len

func (a Slice[T]) Len() int

Len returns number of elements in array

func (Slice[T]) Map

func (a Slice[T]) Map(block func(T) T) Slice[T]

Map will return a new array replacing every element from current array with the return value of the block

func (Slice[T]) Max

func (a Slice[T]) Max(block func(T) int) T

Max returns the element the returned the highest value when passed to block

func (Slice[T]) Min

func (a Slice[T]) Min(block func(T) int) T

Min returns the element the returned the lowest value when passed to block

func (Slice[T]) None added in v0.0.6

func (a Slice[T]) None(predicate func(T) bool) bool

None returns true if no elements in the slice satisfy the predicate function. Returns true for empty slices.

func (Slice[T]) Partition added in v0.0.6

func (s Slice[T]) Partition(predicate func(T) bool) (Slice[T], Slice[T])

Partition divides the slice into two new slices based on the predicate function. Returns two slices: the first contains elements that satisfy the predicate, the second contains elements that do not satisfy the predicate.

func (Slice[T]) Pop

func (a Slice[T]) Pop() (Slice[T], T)

Pop removes the last element from the array, returning new array and the element. Returns the original slice and zero value if slice is empty.

func (Slice[T]) Push

func (a Slice[T]) Push(element T) Slice[T]

Push appends an element to the array returning a new modified array

func (Slice[T]) Reduce

func (a Slice[T]) Reduce(block func(T) bool) Slice[T]

Reduce is an alias for KeepIf

func (Slice[T]) Reject added in v0.0.6

func (a Slice[T]) Reject(block func(T) bool) Slice[T]

Reject returns a new slice containing elements for which the block returns false. It is the logical opposite of Select (or KeepIf).

func (Slice[T]) Reverse

func (a Slice[T]) Reverse() Slice[T]

Reverse returns a new slice with elements in reverse order. The original slice is not modified.

func (Slice[T]) Rotate added in v0.0.6

func (a Slice[T]) Rotate(count int) Slice[T]

Rotate returns a new slice with elements rotated by count positions. Positive count rotates to the left (elements move towards index 0), negative count rotates to the right (elements move towards the end). The original slice is not modified. Inspired by Ruby's Array#rotate method. Example: Slice[int]{1, 2, 3, 4, 5}.Rotate(2) returns [3, 4, 5, 1, 2] Example: Slice[int]{1, 2, 3, 4, 5}.Rotate(-2) returns [4, 5, 1, 2, 3]

Example
nums := Slice[int]{1, 2, 3, 4, 5}

// Rotate left by 2 positions
left := nums.Rotate(2)
fmt.Println(left)

// Rotate right by 2 positions
right := nums.Rotate(-2)
fmt.Println(right)

// Rotate by more than length
bigRotate := nums.Rotate(7) // equivalent to rotating by 2
fmt.Println(bigRotate)
Output:
[3 4 5 1 2]
[4 5 1 2 3]
[3 4 5 1 2]

func (Slice[T]) Sample added in v0.0.6

func (a Slice[T]) Sample() (T, bool)

Sample returns a random element from the slice. If the slice is empty, returns the zero value of T and false. The original slice is not modified.

func (Slice[T]) SampleN added in v0.0.6

func (a Slice[T]) SampleN(n int) Slice[T]

SampleN returns n random elements from the slice without replacement. If n is greater than the slice length, returns all elements in random order. If n is less than or equal to 0, returns an empty slice. The original slice is not modified.

func (Slice[T]) Select

func (a Slice[T]) Select(block func(T) bool) Slice[T]

Select is an alias for KeepIf

func (Slice[T]) SelectUntil added in v0.0.2

func (a Slice[T]) SelectUntil(block func(T) bool) Slice[T]

SelectUntil selects from the start of the slice until the block returns true, excluding the item that returned true.

func (Slice[T]) Shift

func (a Slice[T]) Shift() (T, Slice[T])

Shift will remove the first element of the array returning the element and a modified array

func (Slice[T]) Shuffle

func (a Slice[T]) Shuffle() Slice[T]

Shuffle returns a new slice with elements in random order. The original slice is not modified.

func (Slice[T]) TakeWhile added in v0.0.6

func (a Slice[T]) TakeWhile(predicate func(T) bool) Slice[T]

TakeWhile returns a new slice containing elements from the start of the slice while the predicate returns true. Stops at the first element where predicate returns false.

func (Slice[T]) Tally added in v0.0.6

func (a Slice[T]) Tally() map[T]int

Tally returns a map counting the occurrences of each element in the slice. This is inspired by Ruby's Array#tally method. Example: Slice[int]{1, 2, 2, 3, 3, 3}.Tally() returns map[int]int{1: 1, 2: 2, 3: 3}

Example
// Count word frequencies in a slice
words := Slice[string]{"apple", "banana", "apple", "cherry", "banana", "apple", "date"}
frequencies := words.Tally()

// Sort keys for consistent output
keys := make([]string, 0, len(frequencies))
for k := range frequencies {
	keys = append(keys, k)
}
sort.Strings(keys)

for _, word := range keys {
	fmt.Printf("%s: %d\n", word, frequencies[word])
}
Output:
apple: 3
banana: 2
cherry: 1
date: 1
Example (Numbers)
// Find frequency distribution of dice rolls
rolls := Slice[int]{1, 6, 3, 6, 2, 6, 5, 1, 6, 4}
distribution := rolls.Tally()

// Find the most common roll
maxCount := 0
mostCommon := 0
for roll, count := range distribution {
	if count > maxCount {
		maxCount = count
		mostCommon = roll
	}
}

fmt.Printf("Most common roll: %d (appeared %d times)\n", mostCommon, maxCount)
Output:
Most common roll: 6 (appeared 4 times)

func (Slice[T]) Unique added in v0.0.3

func (a Slice[T]) Unique() Slice[T]

Unique returns a unique list of elements in the slice. order or the result is same order of the items in the source slice

func (Slice[T]) Unshift

func (a Slice[T]) Unshift(element T) Slice[T]

Unshift adds an element to the array returning a new modified array

Jump to

Keyboard shortcuts

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