Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/nwillc/genfuncs

Go 1.18+ polymorphic generic containers and functions.
https://github.com/nwillc/genfuncs

generics go golang

Last synced: about 1 month ago
JSON representation

Go 1.18+ polymorphic generic containers and functions.

Lists

README

        

[![License](https://img.shields.io/github/license/nwillc/genfuncs.svg)](https://tldrlegal.com/license/-isc-license)
[![CI](https://github.com/nwillc/genfuncs/workflows/CI/badge.svg)](https://github.com/nwillc/genfuncs/actions/workflows/CI.yml)
[![codecov.io](https://codecov.io/github/nwillc/genfuncs/coverage.svg?branch=master)](https://codecov.io/github/nwillc/genfuncs?branch=master)
[![goreportcard.com](https://goreportcard.com/badge/github.com/nwillc/genfuncs)](https://goreportcard.com/report/github.com/nwillc/genfuncs)
[![Reference](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white)](https://pkg.go.dev/github.com/nwillc/genfuncs)
[![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go)
[![Releases](https://img.shields.io/github/tag/nwillc/genfuncs.svg)](https://github.com/nwillc/genfuncs/tags)

# Genfuncs Package

Genfuncs implements various functions utilizing Go's Generics to help avoid writing boilerplate code,
in particular when working with containers like heap, list, map, queue, set, slice, etc. Many of the functions are
based on Kotlin's Sequence and Map. Some functional patterns like Result and Promises are presents. Attempts were also
made to introduce more polymorphism into Go's containers. This package, while very usable, is primarily a
proof-of-concept since it is likely Go will provide similar before long. In fact, golang.org/x/exp/slices
and golang.org/x/exp/maps offer some similar functions and I incorporate them here.

## Code Style

The coding style is not always idiomatic, in particular:

- All functions have named return values and those variable are used in the return statements.
- Some places where the `range` build-in could have been used instead use explicit indexing.

Both of these, while less idiomatic, were done because they measurably improve performance.

## General notes:
- A Map interface is provided to allow both Go's normal map and it's sync.Map to be used polymorphically.
- The bias of these functions where appropriate is to be pure, without side effects, at the cost of copying data.
- Examples are found in `*examples_test.go` files or projects like [gordle](https://github.com/nwillc/gordle),
[gorelease](https://github.com/nwillc/gorelease) or [gotimer](https://github.com/nwillc/gotimer).

## License

The code is under the [ISC License](https://github.com/nwillc/genfuncs/blob/master/LICENSE.md).

## Requirements

Build with Go 1.18+

## Getting

```bash
go get github.com/nwillc/genfuncs
```

# Packages
- [genfuncs](<#genfuncs>)
- [genfuncs/container](<#container>)
- [genfuncs/container/gmaps](<#gmaps>)
- [genfuncs/container/gslices](<#gslices>)
- [genfuncs/container/sequences](<#sequences>)
- [genfuncs/promises](<#promises>)
- [genfuncs/results](<#results>)

# genfuncs

```go
import "github.com/nwillc/genfuncs"
```

## Index

- [Variables](<#variables>)
- [func Empty[T any]\(\) (empty T)](<#func-empty>)
- [func Max[T constraints.Ordered](v ...T) (max T)](<#func-max>)
- [func Min[T constraints.Ordered](v ...T) (min T)](<#func-min>)
- [func Ordered[T constraints.Ordered](a, b T) (order int)](<#func-ordered>)
- [func OrderedEqual[O constraints.Ordered](a, b O) (orderedEqualTo bool)](<#func-orderedequal>)
- [func OrderedGreater[O constraints.Ordered](a, b O) (orderedGreaterThan bool)](<#func-orderedgreater>)
- [func OrderedLess[O constraints.Ordered](a, b O) (orderedLess bool)](<#func-orderedless>)
- [type BiFunction](<#type-bifunction>)
- [func TransformArgs[T1, T2, R any](transform Function[T1, T2], operation BiFunction[T2, T2, R]) (fn BiFunction[T1, T1, R])](<#func-transformargs>)
- [type Function](<#type-function>)
- [func Curried[A, R any](operation BiFunction[A, A, R], a A) (fn Function[A, R])](<#func-curried>)
- [func Not[T any](predicate Function[T, bool]) (fn Function[T, bool])](<#func-not>)
- [func OrderedEqualTo[O constraints.Ordered](a O) (fn Function[O, bool])](<#func-orderedequalto>)
- [func OrderedGreaterThan[O constraints.Ordered](a O) (fn Function[O, bool])](<#func-orderedgreaterthan>)
- [func OrderedLessThan[O constraints.Ordered](a O) (fn Function[O, bool])](<#func-orderedlessthan>)
- [type Promise](<#type-promise>)
- [func NewPromise[T any](ctx context.Context, action func(context.Context) *Result[T]) *Promise[T]](<#func-newpromise>)
- [func NewPromiseFromResult[T any](result *Result[T]) *Promise[T]](<#func-newpromisefromresult>)
- [func (p *Promise[T]) Cancel()](<#func-promiset-cancel>)
- [func (p *Promise[T]) OnError(action func(error)) *Promise[T]](<#func-promiset-onerror>)
- [func (p *Promise[T]) OnSuccess(action func(t T)) *Promise[T]](<#func-promiset-onsuccess>)
- [func (p *Promise[T]) Wait() *Result[T]](<#func-promiset-wait>)
- [type Result](<#type-result>)
- [func NewError[T any](err error) *Result[T]](<#func-newerror>)
- [func NewResult[T any](t T) *Result[T]](<#func-newresult>)
- [func NewResultError[T any](t T, err error) *Result[T]](<#func-newresulterror>)
- [func (r *Result[T]) Error() error](<#func-resultt-error>)
- [func (r *Result[T]) MustGet() T](<#func-resultt-mustget>)
- [func (r *Result[T]) Ok() bool](<#func-resultt-ok>)
- [func (r *Result[T]) OnError(action func(e error)) *Result[T]](<#func-resultt-onerror>)
- [func (r *Result[T]) OnSuccess(action func(t T)) *Result[T]](<#func-resultt-onsuccess>)
- [func (r *Result[T]) OrElse(v T) T](<#func-resultt-orelse>)
- [func (r *Result[T]) OrEmpty() T](<#func-resultt-orempty>)
- [func (r *Result[T]) String() string](<#func-resultt-string>)
- [func (r *Result[T]) Then(action func(t T) *Result[T]) *Result[T]](<#func-resultt-then>)
- [type ToString](<#type-tostring>)
- [func StringerToString[T fmt.Stringer]\(\) (fn ToString[T])](<#func-stringertostring>)

## Variables

```go
var (
// Orderings
LessThan = -1
EqualTo = 0
GreaterThan = 1

// Predicates
IsBlank = OrderedEqualTo("")
IsNotBlank = Not(IsBlank)
F32IsZero = OrderedEqualTo(float32(0.0))
F64IsZero = OrderedEqualTo(0.0)
IIsZero = OrderedEqualTo(0)
)
```

```go
var (
// PromiseNoActionErrorMsg indicates a Promise was created for no action.
PromiseNoActionErrorMsg = "promise requested with no action"
// PromisePanicErrorMsg indicates the action of a Promise caused a panic.
PromisePanicErrorMsg = "promise action panic"
)
```

```go
var IllegalArguments = fmt.Errorf("illegal arguments")
```

NoSuchElement error is used by panics when attempts are made to access out of bounds.

```go
var NoSuchElement = fmt.Errorf("no such element")
```

## func [Empty]()

```go
func Empty[T any]\(\) (empty T)
```

Empty return an empty value of type T.

## func [Max]()

```go
func Max[T constraints.Ordered](v ...T) (max T)
```

Max returns max value one or more constraints.Ordered values,

Example

```go
package main

import (
"fmt"

"github.com/nwillc/genfuncs"
)

func main() {
fmt.Println(genfuncs.Max(1, 2))
words := []string{"dog", "cat", "gorilla"}
fmt.Println(genfuncs.Max(words...))
}
```

#### Output

```
2
gorilla
```

## func [Min]()

```go
func Min[T constraints.Ordered](v ...T) (min T)
```

Min returns min value of one or more constraints.Ordered values,

Example

```go
package main

import (
"fmt"

"github.com/nwillc/genfuncs"
)

func main() {
fmt.Println(genfuncs.Min(1, 2))
words := []string{"dog", "cat", "gorilla"}
fmt.Println(genfuncs.Min(words...))
}
```

#### Output

```
1
cat
```

## func [Ordered]()

```go
func Ordered[T constraints.Ordered](a, b T) (order int)
```

Ordered performs old school \-1/0/1 comparison of constraints.Ordered arguments.

## func [OrderedEqual]()

```go
func OrderedEqual[O constraints.Ordered](a, b O) (orderedEqualTo bool)
```

OrderedEqual returns true jf a is ordered equal to b.

## func [OrderedGreater]()

```go
func OrderedGreater[O constraints.Ordered](a, b O) (orderedGreaterThan bool)
```

OrderedGreater returns true if a is ordered greater than b.

## func [OrderedLess]()

```go
func OrderedLess[O constraints.Ordered](a, b O) (orderedLess bool)
```

OrderedLess returns true if a is ordered less than b.

## type [BiFunction]()

BiFunction accepts two arguments and produces a result.

```go
type BiFunction[T, U, R any] func(T, U) R
```

### func [TransformArgs]()

```go
func TransformArgs[T1, T2, R any](transform Function[T1, T2], operation BiFunction[T2, T2, R]) (fn BiFunction[T1, T1, R])
```

TransformArgs uses the function to transform the arguments to be passed to the operation.

Example

```go
package main

import (
"fmt"
"time"

"github.com/nwillc/genfuncs"
)

func main() {
var unixTime = func(t time.Time) int64 { return t.Unix() }
var chronoOrder = genfuncs.TransformArgs(unixTime, genfuncs.OrderedLess[int64])
now := time.Now()
fmt.Println(chronoOrder(now, now.Add(time.Second)))
}
```

#### Output

```
true
```

## type [Function]()

Function is a single argument function.

```go
type Function[T, R any] func(T) R
```

### func [Curried]()

```go
func Curried[A, R any](operation BiFunction[A, A, R], a A) (fn Function[A, R])
```

Curried takes a BiFunction and one argument, and Curries the function to return a single argument Function.

### func [Not]()

```go
func Not[T any](predicate Function[T, bool]) (fn Function[T, bool])
```

Not takes a predicate returning and inverts the result.

### func [OrderedEqualTo]()

```go
func OrderedEqualTo[O constraints.Ordered](a O) (fn Function[O, bool])
```

OrderedEqualTo return a function that returns true if its argument is ordered equal to a.

### func [OrderedGreaterThan]()

```go
func OrderedGreaterThan[O constraints.Ordered](a O) (fn Function[O, bool])
```

OrderedGreaterThan returns a function that returns true if its argument is ordered greater than a.

### func [OrderedLessThan]()

```go
func OrderedLessThan[O constraints.Ordered](a O) (fn Function[O, bool])
```

OrderedLessThan returns a function that returns true if its argument is ordered less than a.

## type [Promise]()

Promise provides asynchronous Result of an action.

```go
type Promise[T any] struct {
// contains filtered or unexported fields
}
```

### func [NewPromise]()

```go
func NewPromise[T any](ctx context.Context, action func(context.Context) *Result[T]) *Promise[T]
```

NewPromise creates a Promise for an action.

### func [NewPromiseFromResult]()

```go
func NewPromiseFromResult[T any](result *Result[T]) *Promise[T]
```

NewPromiseFromResult returns a completed Promise with the specified result.

### func \(\*Promise\[T\]\) [Cancel]()

```go
func (p *Promise[T]) Cancel()
```

Cancel the Promise which will allow any action that is listening on \`\<\-ctx.Done\(\)\` to complete.

### func \(\*Promise\[T\]\) [OnError]()

```go
func (p *Promise[T]) OnError(action func(error)) *Promise[T]
```

OnError returns a new Promise with an error handler waiting on the original Promise.

### func \(\*Promise\[T\]\) [OnSuccess]()

```go
func (p *Promise[T]) OnSuccess(action func(t T)) *Promise[T]
```

OnSuccess returns a new Promise with a success handler waiting on the original Promise.

### func \(\*Promise\[T\]\) [Wait]()

```go
func (p *Promise[T]) Wait() *Result[T]
```

Wait on the completion of a Promise.

## type [Result]()

Result is an implementation of the Maybe pattern. This is mostly for experimentation as it is a poor fit with Go's traditional idiomatic error handling.

```go
type Result[T any] struct {
// contains filtered or unexported fields
}
```

### func [NewError]()

```go
func NewError[T any](err error) *Result[T]
```

NewError for an error.

### func [NewResult]()

```go
func NewResult[T any](t T) *Result[T]
```

NewResult for a value.

### func [NewResultError]()

```go
func NewResultError[T any](t T, err error) *Result[T]
```

NewResultError creates a Result from a value, error tuple.

### func \(\*Result\[T\]\) [Error]()

```go
func (r *Result[T]) Error() error
```

Error of the Result, nil if Ok\(\).

### func \(\*Result\[T\]\) [MustGet]()

```go
func (r *Result[T]) MustGet() T
```

MustGet returns the value of the Result if Ok\(\) or if not, panics with the error.

### func \(\*Result\[T\]\) [Ok]()

```go
func (r *Result[T]) Ok() bool
```

Ok returns the status of Result, is it ok, or an error.

### func \(\*Result\[T\]\) [OnError]()

```go
func (r *Result[T]) OnError(action func(e error)) *Result[T]
```

OnError performs the action if Result is not Ok\(\).

### func \(\*Result\[T\]\) [OnSuccess]()

```go
func (r *Result[T]) OnSuccess(action func(t T)) *Result[T]
```

OnSuccess performs action if Result is Ok\(\).

### func \(\*Result\[T\]\) [OrElse]()

```go
func (r *Result[T]) OrElse(v T) T
```

OrElse returns the value of the Result if Ok\(\), or the value v if not.

### func \(\*Result\[T\]\) [OrEmpty]()

```go
func (r *Result[T]) OrEmpty() T
```

OrEmpty will return the value of the Result or the empty value if Error.

### func \(\*Result\[T\]\) [String]()

```go
func (r *Result[T]) String() string
```

String returns a string representation of Result, either the value or error.

### func \(\*Result\[T\]\) [Then]()

```go
func (r *Result[T]) Then(action func(t T) *Result[T]) *Result[T]
```

Then performs the action on the Result.

## type [ToString]()

ToString is used to create string representations, it accepts any type and returns a string.

```go
type ToString[T any] func(T) string
```

### func [StringerToString]()

```go
func StringerToString[T fmt.Stringer]() (fn ToString[T])
```

StringerToString creates a ToString for any type that implements fmt.Stringer.

Example

```go
package main

import (
"fmt"
"time"

"github.com/nwillc/genfuncs"
)

func main() {
var epoch time.Time
fmt.Println(epoch.String())
stringer := genfuncs.StringerToString[time.Time]()
fmt.Println(stringer(epoch))
}
```

#### Output

```
0001-01-01 00:00:00 +0000 UTC
0001-01-01 00:00:00 +0000 UTC
```

# container

```go
import "github.com/nwillc/genfuncs/container"
```

## Index

- [type Container](<#type-container>)
- [type Deque](<#type-deque>)
- [func NewDeque[T any](t ...T) (degue *Deque[T])](<#func-newdeque>)
- [func (d *Deque[T]) Add(t T)](<#func-dequet-add>)
- [func (d *Deque[T]) AddAll(t ...T)](<#func-dequet-addall>)
- [func (d *Deque[T]) AddLeft(t T)](<#func-dequet-addleft>)
- [func (d *Deque[T]) AddRight(t T)](<#func-dequet-addright>)
- [func (d *Deque[T]) Iterator() Iterator[T]](<#func-dequet-iterator>)
- [func (d *Deque[T]) Len() (length int)](<#func-dequet-len>)
- [func (d *Deque[T]) Peek() (value T)](<#func-dequet-peek>)
- [func (d *Deque[T]) PeekLeft() (value T)](<#func-dequet-peekleft>)
- [func (d *Deque[T]) PeekRight() (value T)](<#func-dequet-peekright>)
- [func (d *Deque[T]) Remove() (value T)](<#func-dequet-remove>)
- [func (d *Deque[T]) RemoveLeft() (value T)](<#func-dequet-removeleft>)
- [func (d *Deque[T]) RemoveRight() (value T)](<#func-dequet-removeright>)
- [func (d *Deque[T]) Values() (values GSlice[T])](<#func-dequet-values>)
- [type GMap](<#type-gmap>)
- [func (m GMap[K, V]) All(predicate genfuncs.Function[V, bool]) (ok bool)](<#func-gmapk-v-all>)
- [func (m GMap[K, V]) Any(predicate genfuncs.Function[V, bool]) (ok bool)](<#func-gmapk-v-any>)
- [func (m GMap[K, V]) Contains(key K) (isTrue bool)](<#func-gmapk-v-contains>)
- [func (m GMap[K, V]) Delete(key K)](<#func-gmapk-v-delete>)
- [func (m GMap[K, V]) Filter(predicate genfuncs.Function[V, bool]) (result GMap[K, V])](<#func-gmapk-v-filter>)
- [func (m GMap[K, V]) FilterKeys(predicate genfuncs.Function[K, bool]) (result GMap[K, V])](<#func-gmapk-v-filterkeys>)
- [func (m GMap[K, V]) ForEach(action func(k K, v V))](<#func-gmapk-v-foreach>)
- [func (m GMap[K, V]) Get(key K) (v V, ok bool)](<#func-gmapk-v-get>)
- [func (m GMap[K, V]) GetOrElse(k K, defaultValue func() V) (value V)](<#func-gmapk-v-getorelse>)
- [func (m GMap[K, V]) Iterator() Iterator[V]](<#func-gmapk-v-iterator>)
- [func (m GMap[K, V]) Keys() (keys GSlice[K])](<#func-gmapk-v-keys>)
- [func (m GMap[K, V]) Len() (length int)](<#func-gmapk-v-len>)
- [func (m GMap[K, V]) Put(key K, value V)](<#func-gmapk-v-put>)
- [func (m GMap[K, V]) Values() (values GSlice[V])](<#func-gmapk-v-values>)
- [type GSlice](<#type-gslice>)
- [func (s GSlice[T]) Filter(predicate genfuncs.Function[T, bool]) GSlice[T]](<#func-gslicet-filter>)
- [func (s GSlice[T]) ForEach(action func(i int, t T))](<#func-gslicet-foreach>)
- [func (s GSlice[T]) Iterator() Iterator[T]](<#func-gslicet-iterator>)
- [func (s GSlice[T]) Len() int](<#func-gslicet-len>)
- [func (s GSlice[T]) Random() (t T)](<#func-gslicet-random>)
- [func (s GSlice[T]) SortBy(order genfuncs.BiFunction[T, T, bool]) (sorted GSlice[T])](<#func-gslicet-sortby>)
- [func (s GSlice[T]) Swap(i, j int)](<#func-gslicet-swap>)
- [func (s GSlice[T]) Values() (values GSlice[T])](<#func-gslicet-values>)
- [type HasValues](<#type-hasvalues>)
- [type Heap](<#type-heap>)
- [func NewHeap[T any](compare genfuncs.BiFunction[T, T, bool], values ...T) (heap *Heap[T])](<#func-newheap>)
- [func (h *Heap[T]) Add(v T)](<#func-heapt-add>)
- [func (h *Heap[T]) AddAll(values ...T)](<#func-heapt-addall>)
- [func (h *Heap[T]) Len() (length int)](<#func-heapt-len>)
- [func (h *Heap[T]) Peek() (value T)](<#func-heapt-peek>)
- [func (h *Heap[T]) Remove() (value T)](<#func-heapt-remove>)
- [func (h *Heap[T]) Values() (values GSlice[T])](<#func-heapt-values>)
- [type Iterator](<#type-iterator>)
- [func NewListIterator[T any](list *List[T]) Iterator[T]](<#func-newlistiterator>)
- [func NewSliceIterator[T any](slice []T) Iterator[T]](<#func-newsliceiterator>)
- [func NewValuesIterator[T any](values ...T) Iterator[T]](<#func-newvaluesiterator>)
- [type List](<#type-list>)
- [func NewList[T any](values ...T) (l *List[T])](<#func-newlist>)
- [func (l *List[T]) Add(value T)](<#func-listt-add>)
- [func (l *List[T]) AddAll(values ...T)](<#func-listt-addall>)
- [func (l *List[T]) AddLeft(value T) (e *ListElement[T])](<#func-listt-addleft>)
- [func (l *List[T]) AddRight(v T) (e *ListElement[T])](<#func-listt-addright>)
- [func (l *List[T]) ForEach(action func(value T))](<#func-listt-foreach>)
- [func (l *List[T]) Iterator() Iterator[T]](<#func-listt-iterator>)
- [func (l *List[T]) Len() (length int)](<#func-listt-len>)
- [func (l *List[T]) PeekLeft() (e *ListElement[T])](<#func-listt-peekleft>)
- [func (l *List[T]) PeekRight() (e *ListElement[T])](<#func-listt-peekright>)
- [func (l *List[T]) Remove(e *ListElement[T]) (t T)](<#func-listt-remove>)
- [func (l *List[T]) SortBy(order genfuncs.BiFunction[T, T, bool]) (result *List[T])](<#func-listt-sortby>)
- [func (l *List[T]) Values() (values GSlice[T])](<#func-listt-values>)
- [type ListElement](<#type-listelement>)
- [func (e *ListElement[T]) Next() (next *ListElement[T])](<#func-listelementt-next>)
- [func (e *ListElement[T]) Prev() (prev *ListElement[T])](<#func-listelementt-prev>)
- [func (e *ListElement[T]) Swap(e2 *ListElement[T])](<#func-listelementt-swap>)
- [type Map](<#type-map>)
- [type MapSet](<#type-mapset>)
- [func (h *MapSet[T]) Add(t T)](<#func-mapsett-add>)
- [func (h *MapSet[T]) AddAll(t ...T)](<#func-mapsett-addall>)
- [func (h *MapSet[T]) Contains(t T) (ok bool)](<#func-mapsett-contains>)
- [func (h *MapSet[T]) Iterator() Iterator[T]](<#func-mapsett-iterator>)
- [func (h *MapSet[T]) Len() (length int)](<#func-mapsett-len>)
- [func (h *MapSet[T]) Remove(t T)](<#func-mapsett-remove>)
- [func (h *MapSet[T]) Values() (values GSlice[T])](<#func-mapsett-values>)
- [type Queue](<#type-queue>)
- [type Sequence](<#type-sequence>)
- [func NewIteratorSequence[T any](iterator Iterator[T]) Sequence[T]](<#func-newiteratorsequence>)
- [type Set](<#type-set>)
- [func NewMapSet[T comparable](t ...T) (set Set[T])](<#func-newmapset>)
- [type SyncMap](<#type-syncmap>)
- [func NewSyncMap[K any, V any]\(\) (syncMap *SyncMap[K, V])](<#func-newsyncmap>)
- [func (s *SyncMap[K, V]) Contains(key K) (contains bool)](<#func-syncmapk-v-contains>)
- [func (s *SyncMap[K, V]) Delete(key K)](<#func-syncmapk-v-delete>)
- [func (s *SyncMap[K, V]) ForEach(f func(key K, value V))](<#func-syncmapk-v-foreach>)
- [func (s *SyncMap[K, V]) Get(key K) (value V, ok bool)](<#func-syncmapk-v-get>)
- [func (s *SyncMap[K, V]) GetAndDelete(key K) (value V, ok bool)](<#func-syncmapk-v-getanddelete>)
- [func (s *SyncMap[K, V]) GetOrPut(key K, value V) (actual V, ok bool)](<#func-syncmapk-v-getorput>)
- [func (s *SyncMap[K, V]) Iterator() Iterator[V]](<#func-syncmapk-v-iterator>)
- [func (s *SyncMap[K, V]) Keys() (keys GSlice[K])](<#func-syncmapk-v-keys>)
- [func (s *SyncMap[K, V]) Len() (length int)](<#func-syncmapk-v-len>)
- [func (s *SyncMap[K, V]) Put(key K, value V)](<#func-syncmapk-v-put>)
- [func (s *SyncMap[K, V]) Values() (values GSlice[V])](<#func-syncmapk-v-values>)

## type [Container]()

Container is a minimal container that HasValues and accepts additional elements.

```go
type Container[T any] interface {

// Add an element to the Container.
Add(t T)
// AddAll elements to the Container.
AddAll(t ...T)
// contains filtered or unexported methods
}
```

## type [Deque]()

Deque is a doubly ended implementation of Queue with default behavior of a Fifo but provides left and right access. Employs a List for storage.

```go
type Deque[T any] struct {
// contains filtered or unexported fields
}
```

### func [NewDeque]()

```go
func NewDeque[T any](t ...T) (degue *Deque[T])
```

NewDeque creates a Deque containing any provided elements.

### func \(\*Deque\[T\]\) [Add]()

```go
func (d *Deque[T]) Add(t T)
```

Add an element to the right of the Deque.

### func \(\*Deque\[T\]\) [AddAll]()

```go
func (d *Deque[T]) AddAll(t ...T)
```

AddAll elements to the right of the Deque.

### func \(\*Deque\[T\]\) [AddLeft]()

```go
func (d *Deque[T]) AddLeft(t T)
```

AddLeft an element to the left of the Deque.

### func \(\*Deque\[T\]\) [AddRight]()

```go
func (d *Deque[T]) AddRight(t T)
```

AddRight an element to the right of the Deque.

### func \(\*Deque\[T\]\) [Iterator]()

```go
func (d *Deque[T]) Iterator() Iterator[T]
```

### func \(\*Deque\[T\]\) [Len]()

```go
func (d *Deque[T]) Len() (length int)
```

Len reports the length of the Deque.

### func \(\*Deque\[T\]\) [Peek]()

```go
func (d *Deque[T]) Peek() (value T)
```

Peek returns the left most element in the Deque without removing it.

### func \(\*Deque\[T\]\) [PeekLeft]()

```go
func (d *Deque[T]) PeekLeft() (value T)
```

PeekLeft returns the left most element in the Deque without removing it.

### func \(\*Deque\[T\]\) [PeekRight]()

```go
func (d *Deque[T]) PeekRight() (value T)
```

PeekRight returns the right most element in the Deque without removing it.

### func \(\*Deque\[T\]\) [Remove]()

```go
func (d *Deque[T]) Remove() (value T)
```

Remove and return the left most element in the Deque.

### func \(\*Deque\[T\]\) [RemoveLeft]()

```go
func (d *Deque[T]) RemoveLeft() (value T)
```

RemoveLeft and return the left most element in the Deque.

### func \(\*Deque\[T\]\) [RemoveRight]()

```go
func (d *Deque[T]) RemoveRight() (value T)
```

RemoveRight and return the right most element in the Deque.

### func \(\*Deque\[T\]\) [Values]()

```go
func (d *Deque[T]) Values() (values GSlice[T])
```

Values in the Deque returned in a new GSlice.

## type [GMap]()

GMap is a generic type employing the standard Go map and implementation Map.

```go
type GMap[K comparable, V any] map[K]V
```

### func \(GMap\[K, V\]\) [All]()

```go
func (m GMap[K, V]) All(predicate genfuncs.Function[V, bool]) (ok bool)
```

All returns true if all values in GMap satisfy the predicate.

### func \(GMap\[K, V\]\) [Any]()

```go
func (m GMap[K, V]) Any(predicate genfuncs.Function[V, bool]) (ok bool)
```

Any returns true if any values in GMap satisfy the predicate.

### func \(GMap\[K, V\]\) [Contains]()

```go
func (m GMap[K, V]) Contains(key K) (isTrue bool)
```

Contains returns true if the GMap contains the given key.

Example

```go
package main

import (
"fmt"
"github.com/nwillc/genfuncs/container"
)

var wordPositions = container.GMap[string, int]{"hello": 1, "world": 2}

func main() {
fmt.Println(wordPositions.Contains("hello"))
fmt.Println(wordPositions.Contains("no"))
}
```

#### Output

```
true
false
```

### func \(GMap\[K, V\]\) [Delete]()

```go
func (m GMap[K, V]) Delete(key K)
```

Delete an entry in the GMap.

### func \(GMap\[K, V\]\) [Filter]()

```go
func (m GMap[K, V]) Filter(predicate genfuncs.Function[V, bool]) (result GMap[K, V])
```

Filter a GMap by a predicate, returning a new GMap that contains only values that satisfy the predicate.

### func \(GMap\[K, V\]\) [FilterKeys]()

```go
func (m GMap[K, V]) FilterKeys(predicate genfuncs.Function[K, bool]) (result GMap[K, V])
```

FilterKeys returns a new GMap that contains only values whose key satisfy the predicate.

### func \(GMap\[K, V\]\) [ForEach]()

```go
func (m GMap[K, V]) ForEach(action func(k K, v V))
```

ForEach performs the given action on each entry in the GMap.

### func \(GMap\[K, V\]\) [Get]()

```go
func (m GMap[K, V]) Get(key K) (v V, ok bool)
```

Get returns an entry from the Map. The returned bool indicates if the key is in the Map.

### func \(GMap\[K, V\]\) [GetOrElse]()

```go
func (m GMap[K, V]) GetOrElse(k K, defaultValue func() V) (value V)
```

GetOrElse returns the value at the given key if it exists or returns the result of defaultValue.

### func \(GMap\[K, V\]\) [Iterator]()

```go
func (m GMap[K, V]) Iterator() Iterator[V]
```

Iterator creates an iterator for the values in the GMap.

### func \(GMap\[K, V\]\) [Keys]()

```go
func (m GMap[K, V]) Keys() (keys GSlice[K])
```

Keys return a GSlice containing the keys of the GMap.

Example

```go
package main

import (
"fmt"
"github.com/nwillc/genfuncs"
"github.com/nwillc/genfuncs/container"
)

var wordPositions = container.GMap[string, int]{"hello": 1, "world": 2}

func main() {
fmt.Println(wordPositions.Keys().SortBy(genfuncs.OrderedLess[string]))
}
```

#### Output

```
[hello world]
```

### func \(GMap\[K, V\]\) [Len]()

```go
func (m GMap[K, V]) Len() (length int)
```

Len is the number of elements in the GMap.

### func \(GMap\[K, V\]\) [Put]()

```go
func (m GMap[K, V]) Put(key K, value V)
```

Put a key and value in the Map.

### func \(GMap\[K, V\]\) [Values]()

```go
func (m GMap[K, V]) Values() (values GSlice[V])
```

Values returns a GSlice of all the values in the GMap.

Example

```go
package main

import (
"fmt"
"github.com/nwillc/genfuncs/container"
)

var wordPositions = container.GMap[string, int]{"hello": 1, "world": 2}

func main() {
wordPositions.Values().ForEach(func(_, i int) { fmt.Println(i) })
}
```

#### Output

```
1
2
```

## type [GSlice]()

GSlice is a generic type corresponding to a standard Go slice that implements HasValues.

```go
type GSlice[T any] []T
```

### func \(GSlice\[T\]\) [Filter]()

```go
func (s GSlice[T]) Filter(predicate genfuncs.Function[T, bool]) GSlice[T]
```

Filter returns a slice containing only elements matching the given predicate.

Example

```go
package main

import (
"fmt"
"github.com/nwillc/genfuncs"
"github.com/nwillc/genfuncs/container"
)

var isGreaterThanZero = genfuncs.OrderedGreaterThan(0)

func main() {
var values container.GSlice[int] = []int{1, -2, 2, -3}
values.Filter(isGreaterThanZero).ForEach(func(_, i int) {
fmt.Println(i)
})
}
```

#### Output

```
1
2
```

### func \(GSlice\[T\]\) [ForEach]()

```go
func (s GSlice[T]) ForEach(action func(i int, t T))
```

ForEach element of the GSlice invoke given function with the element. Syntactic sugar for a range that intends to traverse all the elements, i.e. no exiting midway through.

### func \(GSlice\[T\]\) [Iterator]()

```go
func (s GSlice[T]) Iterator() Iterator[T]
```

Iterator returns an Iterator that will iterate over the GSlice.

### func \(GSlice\[T\]\) [Len]()

```go
func (s GSlice[T]) Len() int
```

Len is the number of elements in the GSlice.

### func \(GSlice\[T\]\) [Random]()

```go
func (s GSlice[T]) Random() (t T)
```

Random returns a random element of the GSlice.

### func \(GSlice\[T\]\) [SortBy]()

```go
func (s GSlice[T]) SortBy(order genfuncs.BiFunction[T, T, bool]) (sorted GSlice[T])
```

SortBy copies a slice, sorts the copy applying the Ordered and returns it. This is not a pure function, the GSlice is sorted in place, the returned slice is to allow for fluid calls in chains.

Example

```go
package main

import (
"fmt"
"github.com/nwillc/genfuncs"
"github.com/nwillc/genfuncs/container"
)

func main() {
var numbers container.GSlice[int] = []int{1, 0, 9, 6, 0}
fmt.Println(numbers)
fmt.Println(numbers.SortBy(genfuncs.OrderedLess[int]))
}
```

#### Output

```
[1 0 9 6 0]
[0 0 1 6 9]
```

### func \(GSlice\[T\]\) [Swap]()

```go
func (s GSlice[T]) Swap(i, j int)
```

Swap two values in the slice.

Example

```go
package main

import (
"fmt"
"github.com/nwillc/genfuncs"
"github.com/nwillc/genfuncs/container"
)

var words container.GSlice[string] = []string{"hello", "world"}

func main() {
words = words.SortBy(genfuncs.OrderedLess[string])
words.Swap(0, 1)
fmt.Println(words)
}
```

#### Output

```
[world hello]
```

### func \(GSlice\[T\]\) [Values]()

```go
func (s GSlice[T]) Values() (values GSlice[T])
```

Values is the GSlice itself.

## type [HasValues]()

HasValues is an interface that indicates a struct contains values that can counted and be retrieved.

```go
type HasValues[T any] interface {
// Len returns length of the Container.
Len() int
// Values returns a copy of the current values in the Container without modifying the contents.
Values() GSlice[T]
}
```

## type [Heap]()

Heap implements an ordered heap of any type which can be min heap or max heap depending on the compare provided. Heap implements Queue.

```go
type Heap[T any] struct {
// contains filtered or unexported fields
}
```

### func [NewHeap]()

```go
func NewHeap[T any](compare genfuncs.BiFunction[T, T, bool], values ...T) (heap *Heap[T])
```

NewHeap return a heap ordered based on the compare and adds any values provided.

Example

```go
package main

import (
"fmt"

"github.com/nwillc/genfuncs"
"github.com/nwillc/genfuncs/container"
)

func main() {
heap := container.NewHeap[int](genfuncs.OrderedLess[int], 3, 1, 4, 2)
for heap.Len() > 0 {
fmt.Print(heap.Remove())
}
fmt.Println()
}
```

#### Output

```
1234
```

### func \(\*Heap\[T\]\) [Add]()

```go
func (h *Heap[T]) Add(v T)
```

Add a value onto the heap.

### func \(\*Heap\[T\]\) [AddAll]()

```go
func (h *Heap[T]) AddAll(values ...T)
```

AddAll the values onto the Heap.

### func \(\*Heap\[T\]\) [Len]()

```go
func (h *Heap[T]) Len() (length int)
```

Len returns current length of the heap.

### func \(\*Heap\[T\]\) [Peek]()

```go
func (h *Heap[T]) Peek() (value T)
```

Peek returns the next element without removing it.

### func \(\*Heap\[T\]\) [Remove]()

```go
func (h *Heap[T]) Remove() (value T)
```

Remove an item off the heap.

### func \(\*Heap\[T\]\) [Values]()

```go
func (h *Heap[T]) Values() (values GSlice[T])
```

Values returns a slice of the values in the Heap in no particular order.

## type [Iterator]()

```go
type Iterator[T any] interface {
HasNext() bool
Next() T
}
```

### func [NewListIterator]()

```go
func NewListIterator[T any](list *List[T]) Iterator[T]
```

### func [NewSliceIterator]()

```go
func NewSliceIterator[T any](slice []T) Iterator[T]
```

### func [NewValuesIterator]()

```go
func NewValuesIterator[T any](values ...T) Iterator[T]
```

## type [List]()

List is a doubly linked list, inspired by list.List but reworked to be generic. List implements Container.

```go
type List[T any] struct {
// contains filtered or unexported fields
}
```

### func [NewList]()

```go
func NewList[T any](values ...T) (l *List[T])
```

NewList instantiates a new List containing any values provided.

### func \(\*List\[T\]\) [Add]()

```go
func (l *List[T]) Add(value T)
```

Add a value to the right of the List.

### func \(\*List\[T\]\) [AddAll]()

```go
func (l *List[T]) AddAll(values ...T)
```

AddAll values to the right of the List.

### func \(\*List\[T\]\) [AddLeft]()

```go
func (l *List[T]) AddLeft(value T) (e *ListElement[T])
```

AddLeft adds a value to the left of the List.

### func \(\*List\[T\]\) [AddRight]()

```go
func (l *List[T]) AddRight(v T) (e *ListElement[T])
```

AddRight adds a value to the right of the List.

### func \(\*List\[T\]\) [ForEach]()

```go
func (l *List[T]) ForEach(action func(value T))
```

ForEach invokes the action for each value in the list.

### func \(\*List\[T\]\) [Iterator]()

```go
func (l *List[T]) Iterator() Iterator[T]
```

Iterator creates an Iterator for the List.

### func \(\*List\[T\]\) [Len]()

```go
func (l *List[T]) Len() (length int)
```

Len returns the number of values in the List.

### func \(\*List\[T\]\) [PeekLeft]()

```go
func (l *List[T]) PeekLeft() (e *ListElement[T])
```

PeekLeft returns the leftmost value in the List or nil if empty.

### func \(\*List\[T\]\) [PeekRight]()

```go
func (l *List[T]) PeekRight() (e *ListElement[T])
```

PeekRight returns the rightmost value in the List or nil if empty.

### func \(\*List\[T\]\) [Remove]()

```go
func (l *List[T]) Remove(e *ListElement[T]) (t T)
```

Remove removes a given value from the List.

### func \(\*List\[T\]\) [SortBy]()

```go
func (l *List[T]) SortBy(order genfuncs.BiFunction[T, T, bool]) (result *List[T])
```

SortBy sorts the List by the order of the order function. This is not a pure function, the List is sorted, the List returned is to allow for fluid call chains. List does not provide efficient indexed access so a Bubble sort is employed.

### func \(\*List\[T\]\) [Values]()

```go
func (l *List[T]) Values() (values GSlice[T])
```

Values returns the values in the list as a GSlice.

## type [ListElement]()

ListElement is an element of List.

```go
type ListElement[T any] struct {
Value T
// contains filtered or unexported fields
}
```

### func \(\*ListElement\[T\]\) [Next]()

```go
func (e *ListElement[T]) Next() (next *ListElement[T])
```

Next returns the next list element or nil.

### func \(\*ListElement\[T\]\) [Prev]()

```go
func (e *ListElement[T]) Prev() (prev *ListElement[T])
```

Prev returns the previous list element or nil.

### func \(\*ListElement\[T\]\) [Swap]()

```go
func (e *ListElement[T]) Swap(e2 *ListElement[T])
```

Swap the values of two ListElements.

## type [Map]()

Map interface to provide a polymorphic and generic interface to map implementations.

```go
type Map[K comparable, V any] interface {
Contains(key K) bool
Delete(key K)
Get(key K) (value V, ok bool)
Put(key K, value V)
ForEach(f func(key K, value V))
Keys() GSlice[K]
// contains filtered or unexported methods
}
```

## type [MapSet]()

MapSet is a Set implementation based on a map. MapSet implements Set.

```go
type MapSet[T comparable] struct {
// contains filtered or unexported fields
}
```

### func \(\*MapSet\[T\]\) [Add]()

```go
func (h *MapSet[T]) Add(t T)
```

Add element to MapSet.

### func \(\*MapSet\[T\]\) [AddAll]()

```go
func (h *MapSet[T]) AddAll(t ...T)
```

AddAll elements to MapSet.

### func \(\*MapSet\[T\]\) [Contains]()

```go
func (h *MapSet[T]) Contains(t T) (ok bool)
```

Contains returns true if MapSet contains element.

### func \(\*MapSet\[T\]\) [Iterator]()

```go
func (h *MapSet[T]) Iterator() Iterator[T]
```

Iterator returns an Iterator of the current state of the MapSet. This creates a copy of the data.

### func \(\*MapSet\[T\]\) [Len]()

```go
func (h *MapSet[T]) Len() (length int)
```

Len returns the length of the MapSet.

### func \(\*MapSet\[T\]\) [Remove]()

```go
func (h *MapSet[T]) Remove(t T)
```

Remove an element from the MapSet.

### func \(\*MapSet\[T\]\) [Values]()

```go
func (h *MapSet[T]) Values() (values GSlice[T])
```

Values returns the elements in the MapSet as a GSlice.

## type [Queue]()

Queue is a container providing some define order when accessing elements. Queue implements Container.

```go
type Queue[T any] interface {

// Peek returns the next element without removing it.
Peek() T
Remove() T
// contains filtered or unexported methods
}
```

## type [Sequence]()

```go
type Sequence[T any] interface {
Iterator() Iterator[T]
}
```

### func [NewIteratorSequence]()

```go
func NewIteratorSequence[T any](iterator Iterator[T]) Sequence[T]
```

## type [Set]()

Set is a Container that contains no duplicate elements.

```go
type Set[T comparable] interface {

// Contains returns true if the Set contains a given element.
Contains(t T) bool
// Remove the element from the Set.
Remove(T)
// contains filtered or unexported methods
}
```

### func [NewMapSet]()

```go
func NewMapSet[T comparable](t ...T) (set Set[T])
```

NewMapSet returns a new Set containing given values.

## type [SyncMap]()

SyncMap is a Map implementation employing sync.Map and is therefore GoRoutine safe.

```go
type SyncMap[K any, V any] struct {
// contains filtered or unexported fields
}
```

### func [NewSyncMap]()

```go
func NewSyncMap[K any, V any]() (syncMap *SyncMap[K, V])
```

NewSyncMap creates a new SyncMap instance.

### func \(\*SyncMap\[K, V\]\) [Contains]()

```go
func (s *SyncMap[K, V]) Contains(key K) (contains bool)
```

Contains returns true if the Map contains the given key.

### func \(\*SyncMap\[K, V\]\) [Delete]()

```go
func (s *SyncMap[K, V]) Delete(key K)
```

Delete an entry from the Map.

### func \(\*SyncMap\[K, V\]\) [ForEach]()

```go
func (s *SyncMap[K, V]) ForEach(f func(key K, value V))
```

ForEach traverses the Map applying the given function to all entries. The sync.Map's any types are cast to the appropriate types.

### func \(\*SyncMap\[K, V\]\) [Get]()

```go
func (s *SyncMap[K, V]) Get(key K) (value V, ok bool)
```

Get the value for the key. The sync.Map any type to cast to the appropriate type. The returned ok value will be false if the map is not contained in the Map.

### func \(\*SyncMap\[K, V\]\) [GetAndDelete]()

```go
func (s *SyncMap[K, V]) GetAndDelete(key K) (value V, ok bool)
```

GetAndDelete returns the value from the SyncMap corresponding to the key, returning it, and deletes it.

### func \(\*SyncMap\[K, V\]\) [GetOrPut]()

```go
func (s *SyncMap[K, V]) GetOrPut(key K, value V) (actual V, ok bool)
```

GetOrPut returns the existing value for the key if present. Otherwise, it puts and returns the given value. The ok result is true if the value was present, false if put.

### func \(\*SyncMap\[K, V\]\) [Iterator]()

```go
func (s *SyncMap[K, V]) Iterator() Iterator[V]
```

Iterator returns an iterator over a snapshot of the current values.

### func \(\*SyncMap\[K, V\]\) [Keys]()

```go
func (s *SyncMap[K, V]) Keys() (keys GSlice[K])
```

Keys returns the keys in the Map by traversing it and casting the sync.Map's any to the appropriate type.

### func \(\*SyncMap\[K, V\]\) [Len]()

```go
func (s *SyncMap[K, V]) Len() (length int)
```

Len returns the element count. This requires a traversal of the Map.

### func \(\*SyncMap\[K, V\]\) [Put]()

```go
func (s *SyncMap[K, V]) Put(key K, value V)
```

Put a key value pair into the Map.

### func \(\*SyncMap\[K, V\]\) [Values]()

```go
func (s *SyncMap[K, V]) Values() (values GSlice[V])
```

Values returns the values in the Map, The sync.Map any values is cast to the Map's type.

# promises

```go
import "github.com/nwillc/genfuncs/promises"
```

## Index

- [Variables](<#variables>)
- [func All[T any](ctx context.Context, promises ...*genfuncs.Promise[T]) *genfuncs.Promise[container.GSlice[T]]](<#func-all>)
- [func Any[T any](ctx context.Context, promises ...*genfuncs.Promise[T]) *genfuncs.Promise[T]](<#func-any>)
- [func Map[A, B any](ctx context.Context, aPromise *genfuncs.Promise[A], then genfuncs.Function[A, *genfuncs.Result[B]]) *genfuncs.Promise[B]](<#func-map>)

## Variables

```go
var (
PromiseAnyNoPromisesErrorMsg = "no any without promises"
PromiseNoneFulfilled = "no promises fulfilled"
)
```

## func [All]()

```go
func All[T any](ctx context.Context, promises ...*genfuncs.Promise[T]) *genfuncs.Promise[container.GSlice[T]]
```

All accepts promises and collects their results, returning a container.GSlice of the results in correlating order, or if \*any\* genfuncs.Promise fails then All returns its error and immediately returns.

## func [Any]()

```go
func Any[T any](ctx context.Context, promises ...*genfuncs.Promise[T]) *genfuncs.Promise[T]
```

Any returns a Promise that will return the first Promise fulfilled, or an error if none were.

## func [Map]()

```go
func Map[A, B any](ctx context.Context, aPromise *genfuncs.Promise[A], then genfuncs.Function[A, *genfuncs.Result[B]]) *genfuncs.Promise[B]
```

Map will Wait for aPromise and then return a new Promise which then maps its result.

# results

```go
import "github.com/nwillc/genfuncs/results"
```

## Index

- [func Map[T, R any](t *genfuncs.Result[T], transform genfuncs.Function[T, *genfuncs.Result[R]]) (r *genfuncs.Result[R])](<#func-map>)
- [func MapError[T, R any](t *genfuncs.Result[T]) (r *genfuncs.Result[R])](<#func-maperror>)

## func [Map]()

```go
func Map[T, R any](t *genfuncs.Result[T], transform genfuncs.Function[T, *genfuncs.Result[R]]) (r *genfuncs.Result[R])
```

Map one Result type to another employing a transform.

## func [MapError]()

```go
func MapError[T, R any](t *genfuncs.Result[T]) (r *genfuncs.Result[R])
```

MapError Result of one type to another.

# gslices

```go
import "github.com/nwillc/genfuncs/container/gslices"
```

## Index

- [func Distinct[T comparable](slice container.GSlice[T]) (distinct container.GSlice[T])](<#func-distinct>)
- [func FlatMap[T, R any](slice container.GSlice[T], transform genfuncs.Function[T, container.GSlice[R]]) (result container.GSlice[R])](<#func-flatmap>)
- [func GroupBy[T any, K comparable](slice container.GSlice[T], keyFor maps.KeyFor[T, K]) (result container.GMap[K, container.GSlice[T]])](<#func-groupby>)
- [func Map[T, R any](slice container.GSlice[T], transform genfuncs.Function[T, R]) container.GSlice[R]](<#func-map>)
- [func ToSet[T comparable](slice container.GSlice[T]) (set container.Set[T])](<#func-toset>)

## func [Distinct]()

```go
func Distinct[T comparable](slice container.GSlice[T]) (distinct container.GSlice[T])
```

Distinct returns a slice containing only distinct elements from the given slice.

Example

```go
package main

import (
"fmt"
"github.com/nwillc/genfuncs/container/gslices"
)

func main() {
values := []int{1, 2, 2, 3, 1, 3}
gslices.Distinct(values).ForEach(func(_, i int) {
fmt.Println(i)
})
}
```

#### Output

```
1
2
3
```

## func [FlatMap]()

```go
func FlatMap[T, R any](slice container.GSlice[T], transform genfuncs.Function[T, container.GSlice[R]]) (result container.GSlice[R])
```

FlatMap returns a slice of all elements from results of transform being invoked on each element of original slice, and those resultant slices concatenated.

Example

```go
package main

import (
"fmt"
"github.com/nwillc/genfuncs"
"github.com/nwillc/genfuncs/container"
"github.com/nwillc/genfuncs/container/gslices"
"strings"
)

var words container.GSlice[string] = []string{"hello", "world"}

func main() {
slicer := func(s string) container.GSlice[string] { return strings.Split(s, "") }
fmt.Println(gslices.FlatMap(words.SortBy(genfuncs.OrderedLess[string]), slicer))
}
```

#### Output

```
[h e l l o w o r l d]
```

## func [GroupBy]()

```go
func GroupBy[T any, K comparable](slice container.GSlice[T], keyFor maps.KeyFor[T, K]) (result container.GMap[K, container.GSlice[T]])
```

GroupBy groups elements of the slice by the key returned by the given keySelector function applied to each element and returns a map where each group key is associated with a slice of corresponding elements.

Example

```go
package main

import (
"fmt"
"github.com/nwillc/genfuncs"
"github.com/nwillc/genfuncs/container/gslices"
)

func main() {
oddEven := func(i int) *genfuncs.Result[string] {
if i%2 == 0 {
return genfuncs.NewResult("EVEN")
}
return genfuncs.NewResult("ODD")
}
numbers := []int{1, 2, 3, 4}
grouped := gslices.GroupBy(numbers, oddEven)
fmt.Println(grouped["ODD"])
}
```

#### Output

```
[1 3]
```

## func [Map]()

```go
func Map[T, R any](slice container.GSlice[T], transform genfuncs.Function[T, R]) container.GSlice[R]
```

Map returns a new container.GSlice containing the results of applying the given transform function to each element in the original slice.

Example

```go
package main

import (
"fmt"
"github.com/nwillc/genfuncs/container/gslices"
)

func main() {
numbers := []int{69, 88, 65, 77, 80, 76, 69}
toString := func(i int) string { return string(rune(i)) }
fmt.Println(gslices.Map(numbers, toString))
}
```

#### Output

```
[E X A M P L E]
```

## func [ToSet]()

```go
func ToSet[T comparable](slice container.GSlice[T]) (set container.Set[T])
```

ToSet creates a Set from the elements of the GSlice.

# maps

```go
import "github.com/nwillc/genfuncs/container/maps"
```

## Index

- [func Map[K comparable, V any, R any](m container.Map[K, V], transform genfuncs.BiFunction[K, V, R]) (result container.GSlice[R])](<#func-map>)
- [func Merge[K comparable, V any](mv ...container.Map[K, container.GSlice[V]]) (result container.GMap[K, container.GSlice[V]])](<#func-merge>)
- [type Entry](<#type-entry>)
- [func NewEntry[K comparable, V any](k K, v V) *Entry[K, V]](<#func-newentry>)
- [type KeyFor](<#type-keyfor>)
- [type KeyValueFor](<#type-keyvaluefor>)
- [type ValueFor](<#type-valuefor>)

## func [Map]()

```go
func Map[K comparable, V any, R any](m container.Map[K, V], transform genfuncs.BiFunction[K, V, R]) (result container.GSlice[R])
```

Map returns a GSlice containing the results of applying the given transform function to each element in the GMap.

## func [Merge]()

```go
func Merge[K comparable, V any](mv ...container.Map[K, container.GSlice[V]]) (result container.GMap[K, container.GSlice[V]])
```

Merge merges maps of container.GSlice's together into a new map appending the container.GSlice's when collisions occur.

## type [Entry]()

Entry can be used to hold onto a key/value.

```go
type Entry[K comparable, V any] struct {
Key K
Value V
}
```

### func [NewEntry]()

```go
func NewEntry[K comparable, V any](k K, v V) *Entry[K, V]
```

## type [KeyFor]()

KeyFor is used for generating keys from types, it accepts any type and returns a comparable key for it.

```go
type KeyFor[T any, K comparable] func(T) *genfuncs.Result[K]
```

## type [KeyValueFor]()

KeyValueFor is used to generate a key and value from a type, it accepts any type, and returns a comparable key and any value.

```go
type KeyValueFor[T any, K comparable, V any] func(T) *genfuncs.Result[*Entry[K, V]]
```

## type [ValueFor]()

ValueFor given a comparable key will return a value for it.

```go
type ValueFor[K comparable, T any] func(K) *genfuncs.Result[T]
```

# sequences

```go
import "github.com/nwillc/genfuncs/container/sequences"
```

## Index

- [func All[T any](sequence container.Sequence[T], predicate genfuncs.Function[T, bool]) (result bool)](<#func-all>)
- [func Any[T any](sequence container.Sequence[T], predicate genfuncs.Function[T, bool]) (result bool)](<#func-any>)
- [func Associate[T any, K comparable, V any](sequence container.Sequence[T], keyValueFor maps.KeyValueFor[T, K, V]) (result *genfuncs.Result[container.GMap[K, V]])](<#func-associate>)
- [func AssociateWith[K comparable, V any](sequence container.Sequence[K], valueFor maps.ValueFor[K, V]) (result *genfuncs.Result[container.GMap[K, V]])](<#func-associatewith>)
- [func Collect[T any](s container.Sequence[T], c container.Container[T])](<#func-collect>)
- [func Compare[T any](s1, s2 container.Sequence[T], comparator func(t1, t2 T) int) int](<#func-compare>)
- [func Distinct[T comparable](s container.Sequence[T]) container.Sequence[T]](<#func-distinct>)
- [func Find[T any](sequence container.Sequence[T], predicate genfuncs.Function[T, bool]) *genfuncs.Result[T]](<#func-find>)
- [func FindLast[T any](sequence container.Sequence[T], predicate genfuncs.Function[T, bool]) *genfuncs.Result[T]](<#func-findlast>)
- [func FlatMap[T, R any](sequence container.Sequence[T], transform genfuncs.Function[T, container.Sequence[R]]) (result container.Sequence[R])](<#func-flatmap>)
- [func Fold[T, R any](sequence container.Sequence[T], initial R, operation genfuncs.BiFunction[R, T, R]) (result R)](<#func-fold>)
- [func ForEach[T any](sequence container.Sequence[T], action func(t T))](<#func-foreach>)
- [func IsSorted[T any](sequence container.Sequence[T], order genfuncs.BiFunction[T, T, bool]) (ok bool)](<#func-issorted>)
- [func JoinToString[T any](sequence container.Sequence[T], stringer genfuncs.ToString[T], separator string, prefix string, postfix string) string](<#func-jointostring>)
- [func Map[T, R any](sequence container.Sequence[T], transform genfuncs.Function[T, R]) container.Sequence[R]](<#func-map>)
- [func NewSequence[T any](values ...T) (sequence container.Sequence[T])](<#func-newsequence>)

## func [All]()

```go
func All[T any](sequence container.Sequence[T], predicate genfuncs.Function[T, bool]) (result bool)
```

All returns true if all elements in the sequence match the predicate.

## func [Any]()

```go
func Any[T any](sequence container.Sequence[T], predicate genfuncs.Function[T, bool]) (result bool)
```

Any returns true if any element of the sequence matches the predicate.

## func [Associate]()

```go
func Associate[T any, K comparable, V any](sequence container.Sequence[T], keyValueFor maps.KeyValueFor[T, K, V]) (result *genfuncs.Result[container.GMap[K, V]])
```

Associate returns a map containing key/values created by applying a function to each value of the container.Iterator returned by the container.Sequence.

Example

```go
package main

import (
"fmt"
"github.com/nwillc/genfuncs"
"github.com/nwillc/genfuncs/container"
"github.com/nwillc/genfuncs/container/maps"
"github.com/nwillc/genfuncs/container/sequences"
"strings"
)

func main() {
byLastName := func(n string) *genfuncs.Result[*maps.Entry[string, string]] {
parts := strings.Split(n, " ")
return genfuncs.NewResult(maps.NewEntry(parts[1], n))
}
names := sequences.NewSequence[string]("fred flintstone", "barney rubble")
sequences.Associate(names, byLastName).
OnSuccess(func(nameMap container.GMap[string, string]) {
fmt.Println(nameMap["rubble"])
})

}
```

#### Output

```
barney rubble
```

## func [AssociateWith]()

```go
func AssociateWith[K comparable, V any](sequence container.Sequence[K], valueFor maps.ValueFor[K, V]) (result *genfuncs.Result[container.GMap[K, V]])
```

AssociateWith returns a Map where keys are elements from the given sequence and values are produced by the valueSelector function applied to each element.

Example

```go
package main

import (
"fmt"
"github.com/nwillc/genfuncs"
"github.com/nwillc/genfuncs/container"
"github.com/nwillc/genfuncs/container/sequences"
)

func main() {
oddEven := func(i int) *genfuncs.Result[string] {
if i%2 == 0 {
return genfuncs.NewResult("EVEN")
}
return genfuncs.NewResult("ODD")
}
numbers := sequences.NewSequence[int](1, 2, 3, 4)
sequences.AssociateWith[int, string](numbers, oddEven).OnSuccess(func(odsEvensMap container.GMap[int, string]) {
fmt.Println(odsEvensMap[2])
fmt.Println(odsEvensMap[3])
})
}
```

#### Output

```
EVEN
ODD
```

## func [Collect]()

```go
func Collect[T any](s container.Sequence[T], c container.Container[T])
```

Collect elements from a Sequence into a Container.

## func [Compare]()

```go
func Compare[T any](s1, s2 container.Sequence[T], comparator func(t1, t2 T) int) int
```

Compare two sequences with a comparator returning less/equal/greater \(\-1/0/1\) and return comparison of the two.

## func [Distinct]()

```go
func Distinct[T comparable](s container.Sequence[T]) container.Sequence[T]
```

Distinct collects a sequence into a container.Set and returns it as a Sequence.

## func [Find]()

```go
func Find[T any](sequence container.Sequence[T], predicate genfuncs.Function[T, bool]) *genfuncs.Result[T]
```

Find returns the first element matching the given predicate, or Result error of NoSuchElement if not found.

## func [FindLast]()

```go
func FindLast[T any](sequence container.Sequence[T], predicate genfuncs.Function[T, bool]) *genfuncs.Result[T]
```

FindLast returns the last element matching the given predicate, or Result error of NoSuchElement if not found.

## func [FlatMap]()

```go
func FlatMap[T, R any](sequence container.Sequence[T], transform genfuncs.Function[T, container.Sequence[R]]) (result container.Sequence[R])
```

FlatMap returns a sequence of all elements from results of valueFor being invoked on each element of original sequence, and those resultant slices concatenated.

## func [Fold]()

```go
func Fold[T, R any](sequence container.Sequence[T], initial R, operation genfuncs.BiFunction[R, T, R]) (result R)
```

Fold accumulates a value starting with an initial value and applying operation to each value of the container.Iterator returned by the container.Sequence.

Example

```go
package main

import (
"fmt"
"github.com/nwillc/genfuncs/container/sequences"
)

func main() {
sequence := sequences.NewSequence(1, 2, 3, 4)
sum := sequences.Fold(sequence, 0, func(prior, value int) int {
return prior + value
})
fmt.Println(sum)
}
```

#### Output

```
10
```

## func [ForEach]()

```go
func ForEach[T any](sequence container.Sequence[T], action func(t T))
```

ForEach calls action for each element of a Sequence.

## func [IsSorted]()

```go
func IsSorted[T any](sequence container.Sequence[T], order genfuncs.BiFunction[T, T, bool]) (ok bool)
```

IsSorted returns true if the GSlice is sorted by order.

## func [JoinToString]()

```go
func JoinToString[T any](sequence container.Sequence[T], stringer genfuncs.ToString[T], separator string, prefix string, postfix string) string
```

JoinToString creates a string from all the elements of a Sequence using the stringer on each, separating them using separator, and using the given prefix and postfix.

## func [Map]()

```go
func Map[T, R any](sequence container.Sequence[T], transform genfuncs.Function[T, R]) container.Sequence[R]
```

Map elements in a Sequence to a new Sequence having applied the valueFor to them.

## func [NewSequence]()

```go
func NewSequence[T any](values ...T) (sequence container.Sequence[T])
```

NewSequence creates a sequence from the provided values.

# version

```go
import "github.com/nwillc/genfuncs/gen/version"
```

## Index

- [Constants](<#constants>)

## Constants

Version number for official releases.

```go
const Version = "v0.20.0"
```

# tests

```go
import "github.com/nwillc/genfuncs/internal/tests"
```

## Index

- [Constants](<#constants>)
- [func MaybeRunExamples(t *testing.T)](<#func-mayberunexamples>)

## Constants

```go
const RunExamples = "RUN_EXAMPLES"
```

## func [MaybeRunExamples]()

```go
func MaybeRunExamples(t *testing.T)
```

Generated by [gomarkdoc]()