gotools

package module
v2.0.4 Latest Latest
Warning

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

Go to latest
Published: Jul 2, 2025 License: MIT Imports: 15 Imported by: 0

README

gotools

Functionality that ought to be part of the Go standard library and that are standard – particularly to functional programming languages. Examples are:

  • Concat to concatenate a number of slices into one big slice
  • Map to apply a function to all elements of a slice and returns a slice of the results)
  • Reduce to apply a function to elements of the slice, returning f(f(f(x1, x2), x3), x4)...
  • Sets (with standard functions such as intersections and unions)

Other functions just have an awkward syntax (such as the sort.Slice function where the sorting function takes indices instead of instances). So I added a Sort function that I found easier to consume.

Such functions are possible since generics are available in Go – i.e. version 1.18. My expectation is that some of this functionality will be provided by the Go standard library in the long run.

The library is by no means complete. (I implemented what I needed rather than taking something like the Clojure standard library as a blueprint.) So functionality you love might be missing without rational reason. Feel free to request such functionality.

All functionality is backed with tests and used. However, some parts could be of better efficiency. (Particularly, the implementation of sets is slower as the implementation in e.g. Java.) However, all functionality should be at least as good as what you can hack down on your own in a cup of hours.

One goal of this library is also to provide simple functionality. You should have no issues forking and maintaining this library by yourself in case you find my support no-efficient.

Still, the current state is sufficient for myself.

Incompatible Changes in Version 2

  • Max() and Min() have been removed. Instead, functions of the standard library slices.Min() and slices.Max should be used for slices and the primitives max and min for single values.
  • MakeSet() now operates on single values instead of slices. I.e. MakeSet([]int{1,2,3}) becomes MakeSet(1,2,3) and MakeSet(slc) becomes MakeSet(slc...).

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Abs

func Abs[N Number](n N) N

Abs returns the absolute value of a number

func Assert added in v2.0.1

func Assert(condition bool, parameters ...any)

Assert panics if a condition is not met. It should be used to signal a situation that cannot occur. (So, if the situation occurs, there is a bug in the program logic itself.)

func Assume added in v2.0.1

func Assume(condition bool, parameters ...any)

Assume behaves technically like assert. The difference is the semantic. Assume should be used when you – during dirty programming – assume a situation should not appear and you avoid proper error handling. In case this is violated, you search for different types of errors. Also, you should replace assumes with proper error handling before going productive.

func BigGCD

func BigGCD(a, b *big.Int) *big.Int

BigGCD returns the greatest common divisor of two big.Int variables.

func BigInt

func BigInt[I Integer](n I) *big.Int

BigInt creates a big integer from any given integer type. That's how big.NewInt ought to be typed.

func BigLCM

func BigLCM(a, b *big.Int) *big.Int

BigLCM returns the least common multiple of two big.Int variables

func Concat

func Concat[A any](inputSlices ...[]A) []A

Concat concatenates slices Example:

Concat([]int{1,2,3}, []int{2,3}, []int{8})

returns

[]int{1,2,3,2,3,8}

func CopySlice

func CopySlice[C any](slc []C) []C

CopySlice copies a slice (it does not copy the values, so it's not a deep copy)

func DropWhile

func DropWhile[A any](slc []A, f func(A) bool) []A

DropWhile returns the given slice except for the first elements of a slice for which a given function returns true. Example:

DropWhile([]int{1, 2, 3, 4}, func(n int) bool { return n < 3 })

returns

[]int{3, 4}

func Every

func Every[A any](slc []A, pred func(A) bool) bool

Every returns true if `pred` returns true for every value of a sequence. Example:

Every([]int{2, 3, 4}, func(n int) bool { return n > 1 }) // returns true
Every([]int{2, 0, 4}, func(n int) bool { return n > 1 }) // returns false
Every([]int{}, func(n int) bool { return n > 1 })        // returns true

func FileExists

func FileExists(filename string) bool

Tests if a file exists

func Filter

func Filter[A any](slc []A, f func(A) bool) []A

Filter takes a slice slc and a function f. It returns a new slice containing all values of that slice for which f returns true. Example:

Filter([]int{1, 2, 3, 4}, func(n int) bool { return n%2 == 0 })

returns

[]int{2, 4}

func Future

func Future[A any](f func() A) func() A

Future executes a function f in background. It returns a function that will wait for the result and returns it.

The return value will be buffered, so the function can be called multiple times. I.e. it can be treated as a regular result and be passed around without worrying who calls it first. Example:

futureValue1 := Future(func() int {
    time.Sleep(100 * time.Millisecond)
    return 1
})
futureValue2 := Future(func() int {
    time.Sleep(100 * time.Millisecond)
    return 2
})
fmt.Printf("Values: %d, %d\n", futureValue1(), futureValue2())

will print "Values: 1, 2" and it will run for little more than 100ms.

func FutureWithError

func FutureWithError[A any](f func() (A, error)) func() (A, error)

FutureWithError (just like Future – but with additional error output) executes a function f in background. It returns a function that will wait for the result and returns it.

The return value will be buffered, so the function can be called multiple times. I.e. it can be treated as a regular result and be passed around without worrying who calls it first.

func FutureWithOk

func FutureWithOk[A any](f func() (A, bool)) func() (A, bool)

FutureWithOk (just like Future – but with additional ok output) executes a function f in background. It returns a function that will wait for the result and returns it.

The return value will be buffered, so the function can be called multiple times. I.e. it can be treated as a regular result and be passed around without worrying who calls it first.

func GCD

func GCD[I Integer](a, b I) I

GCD returns the greatest common divisor of two integers.

func GetIntegersInString

func GetIntegersInString(line string) []int

GetIntegersInString returns all integers in a given string

func GetKeys

func GetKeys[A comparable, B any](m map[A]B) []A

GetKeys returns the keys of a map Example:

GetKeys(map[int]string{1:"one", 2:"two"})

returns (in undefined order!)

[]int{1, 2}

func GetValues

func GetValues[A comparable, B any](m map[A]B) []B

GetValues returns the values of a map Example:

GetValues(map[int]string{1:"one", 2:"two"})

returns (in undefined order!)

[]string{"one", "two"}

func Identity added in v2.0.1

func Identity[A any](v A) A

Identity plainly returns it's input value. It can be used e.g. for PartitionBy, Example:

PartitionBy([]int{1,1,2,1,3,3}, Identity[int])

returns `[][]int{{1,1}, {2}, {1}, {3,3}}`

func IndexOf added in v2.0.1

func IndexOf[T comparable](slc []T, elt T) (int, bool)

IndexOf returns the index of elt in slice slc

func IntSequence

func IntSequence(length int, from ...int) []int

IntSequence returns a sequence of consecutive integers of a given length starting with "from" (default: 0 ) Examples:

IntSequence(3)

returns []int{0, 1, 2};

IntSequence(3, 1)

returns []int{1, 2, 3}

func LCM

func LCM[I Integer](a, b I) I

LCM returns the least common multiple of two integers

func Map

func Map[A any, B any](slc []A, f func(A) B) []B

Map maps all values of a slice with a function f. Example:

Map([]string{"1", "2", "3"}, StringToInt)

returns

[]int{1, 2, 3}

func MapAtHash

func MapAtHash[KeyType comparable, ValueTypeA any, ValueTypeB any](
	m map[KeyType]ValueTypeA,
	f func(ValueTypeA) ValueTypeB) map[KeyType]ValueTypeB

MapAtHash provides a map functionality for hashmaps, i.e. it applies a given function to the /values/ of a hashmap. Example:

MapAtHash(map[string]string{"a": "1", "b": "2"}, StringToInt)

returns

map[string]int{"a": 1, "b": 2},

func MapHasKey

func MapHasKey[A comparable, B any](m map[A]B, key A) bool

MapHasKey checks if a hashmap contains a given key

func MapHashKeys

func MapHashKeys[KeyTypeA comparable, KeyTypeB comparable, ValueType any](
	m map[KeyTypeA]ValueType,
	f func(KeyTypeA) KeyTypeB) map[KeyTypeB]ValueType

MapHashKeys provides a map functionality for hashmaps, i.e. it applies a given function to the /keys/ of a hashmap. Example:

MapHashKeys(map[string]string{"1": "a", "2": "b"}, StringToInt)

returns

map[int]string{1: "a", 2: "b"}

func Partial2L

func Partial2L[A any, B any, C any, ResultType any](f func(A, B, C) ResultType, b B, c C) func(A) ResultType

Partial2L (similar to Partial2R takes a function with three arguments and the last two arguments. It returns a function with only one argument. Example

func subtract2(a int, b int, c int) int { return a - b - c }
subtractThree := Partial2L(subtract2, 1, 2)

now, subtractThree(10) returns 7

func Partial2R

func Partial2R[A any, B any, C any, ResultType any](f func(A, B, C) ResultType, a A, b B) func(C) ResultType

Partial2R (similar to Partial2L takes a function with three arguments and the first two arguments. It returns a function with only one argument. Example

func subtract2(a int, b int, c int) int { return a - b - c }
f := Partial2R(subtract2, 10, 2)

now, f(3) returns 5

func PartialL

func PartialL[A any, B any, ResultType any](f func(A, B) ResultType, b B) func(A) ResultType

PartialL (similar to PartialR takes a function with two arguments and one (the second) argument. It returns a function with only one argument. Example

func add(a int, b int) int { return a + b }
addTwo := PartialL(add, 2)

now, addTwo(3) returns 5 This is handy for mapping, e.g.:

Map([]int{1, 2, 3}, PartialL(add,10))

returns

[]int{11, 12, 13}

func PartialR

func PartialR[A any, B any, ResultType any](f func(A, B) ResultType, a A) func(B) ResultType

PartialR (similar to PartialL takes a function with two arguments and one (the first) argument. It returns a function with only one argument. Example

func subtract(a int, b int) int { return a - b }
subtractFromTen := PartialR(subtract, 10)

Now, subtractFromTen(3) returns 7. This is handy for mapping, e.g.:

Map([]int{1, 2, 3}, PartialR(subtract, 10))

returns

[]int{9, 8, 7}

func PartitionAt

func PartitionAt[C comparable](slc []C, compareValue C) [][]C

PartitionAt imagines a slice to be devided into blocks by `compareValue`. It returns the blocks as slice of slices with entries of `compareValue` removed. Example:

PartitionAt([]int{1, 2, 0, 3, 4, 0, 5}, 0)

returns `[][]int{{1, 2}, {3, 4}, {5}}`

func PartitionBy

func PartitionBy[A any, B comparable](slc []A, f func(A) B) [][]A

PartitionBy imagines a slice to be devided into blocks for which `f` returns a different value. It returns the blocks as slice of slices. No entries are removed. Example:

PartitionBy([]int{1, 2, 3, 4, 5}, func(n int) int {
  return n / 2
})

returns `[][]int{{1}, {2, 3}, {4, 5}}`

func Permutations added in v2.0.4

func Permutations[T any](slice []T) [][]T

Permutations takes a slice of values and returns a slice of slices containing each possible permutation.

The original slice needs to be quite small. (The function itself imposes a hard boundary of 20, but practically also lower values will likely exceed the memory.) Use PermutationsIter() if you don't want to use up memory.

Example:

Permutations([]int{1,2,3})

returns [][]int{{1,2,3}, {1,3,2}, {2,1,3}, {2,3,1}, {3,1,2}, {3,2,1}} (in arbitrary order).

func PermutationsIter added in v2.0.4

func PermutationsIter[T any](slice []T) iter.Seq[[]T]

PermutationsIter takes a slice of values and returns an iterator to loop across all iterations of elements of that slice.

Different from Permutations(), the concrete permutations are not calculated, so the size of the slice can be large without using space.

Example:

for perm := range PermutationsIter([]int{1,2}) {
    fmt.Println(perm)
}

prints []int{1,2} and []int{2,1} (in arbitrary order).

func Prod

func Prod[N Number](slc []N) N

Prod takes a slice of numbers. It returns the product of all values of that slice. If the slice is empty, it returns 1. Examples:

Prod([]int{1,2,3})

returns 6

Prod([]float64{1.5, 2, 4})

returns 12.0 (a float value)

func Randomize added in v2.0.2

func Randomize[T any](slice []T)

Randomize shuffles the elements in a slice in random order. Each order is returned with equal probability.

func Randomized added in v2.0.4

func Randomized[T any](slice []T) []T

Randomized returns a slice containing the values of the original slice in random order. Each order is returned with equal probability.

func Range added in v2.0.2

func Range(n int) []int

Range returns a slice containing values 0,...,n-1 in increasing order

func RangeFromTo added in v2.0.2

func RangeFromTo(from, to int) []int

RangeFromTo returns a slice containing values from,...,to-1 in increasing order

func ReadBytes added in v2.0.2

func ReadBytes(filename string) ([]byte, error)

ReadBytes reads binary contents from a file and returns it as bytes.

func ReadJsonFile

func ReadJsonFile(filename string, data any) error

ReadJsonFile reads a JSON file into an existing object

func ReadLines

func ReadLines(filename string) ([]string, error)

ReadLines reads a text file named filename and returns its contents a slice of strings

func Reduce

func Reduce[A any, B any](f func(A, B) A, startValue A, slc []B) A

Reduce is a classic reduce as used in functional programming. It takes a binary function, a start value and a slice of values and calculates f(f(f(f(startValue, slc[0]), slc[1]), slc[2]) ...) Example:

func add(a int, b int) int { return a + b }
Reduce(add, 1, []int{2, 3, 4})

returns 10

func Remove

func Remove[A any](slc []A, f func(A) bool) []A

Remove takes a slice slc and a function f. It returns a new slice containing all values of that slice for which f returns true. Example:

Remove([]int{1, 2, 3, 4}, func(n int) bool { return n%2 == 0 })

returns

[]int{1, 3}

func Repeat

func Repeat[A any](elt A, n int) []A

Repeat returns a sequence that repeats a given element n times. Example:

Repeat("s", 3)

returns

[]string{"s", "s", "s"}

Note: This works well only with value types (or constants – if this is intended). To produce individual reference values, use Repeatedly

func Repeatedly

func Repeatedly[A any](n int, f func() A) []A

Repeatedly (similar to Repeat) executes a function n times returning a slice of n times its result. Purpose is to permit the repeated construction of a value. Example: After

r1 := Repeatedly(2, func() []int {
  return []int{1}
})
r2 := Repeat([]int{1}, 2)

r1 and r2 both look like [][]int{{1}, {1}}. But after

r1[0][0] = 2
r2[0][0] = 2

r1[1][0] is 1, while r2[1][0] is 2, because r2[0] and r2[1] point to the same slice.

func Reverse

func Reverse[A any](slc []A) []A

Reverse reverses a slice Example:

Prod([]int{1,2,3})

returns []int{3,2,1}

func Some

func Some[A any](slc []A, pred func(A) bool) bool

Some returns true if `pred` returns true for at least one value of a sequence.

Some([]int{2, 3, 4}, func(n int) bool { return n < 1 }) // returns false
Some([]int{2, 0, 4}, func(n int) bool { return n < 1 }) // returns true
Some([]int{}, func(n int) bool { return n < 1 })        // returns false

func SortBy

func SortBy[A any](slc []A, less func(A, A) bool) []A

SortBy (similar to sort.Slice) sorts elements in slice using a comparator (less) function. The corresponding slice is altered and returned.

func SortLex added in v2.0.4

func SortLex[T cmp.Ordered](slice [][]T)

SortLex takes a slice of slices and sorts it in lexicographic order.

func SortStable

func SortStable[A any](slc []A, less func(A, A) bool) []A

SortStable (similar to sort.SliceStable) sorts elements in slice using a comparator (less) function. The corresponding slice is altered and returned.

func SortedLex added in v2.0.4

func SortedLex[T cmp.Ordered](slice [][]T) [][]T

SortedLex copies a slice of slices, sorts it in lexicographic order and returns it.

func StringToInt

func StringToInt(st string) int

StringToInt converts the given string to an integer. It panics if this is not possible.

func Sum

func Sum[N Number](slc []N) N

Sum takes a slice of numbers. It sums all values of that slice. If the slice is empty, it returns 0. Examples:

Sum([]int{1,2,3})

returns 6

Sum([]float64{1.5, 2.5, 3.5})

returns 7.5

func TakeWhile

func TakeWhile[A any](slc []A, f func(A) bool) []A

TakeWhile returns the first elements of a slice for which a given function returns true. Example:

TakeWhile([]int{1, 2, 3, 4}, func(n int) bool { return n < 3 })

returns

[]int{1, 2}

func Ternary added in v2.0.1

func Ternary[A any](condition bool, trueVal A, falseVal A) A

Ternary is a weak substitute for the missing ternary operator. I consider it as an act of self-defense from strange language lawyers that think that

var x int
if useOne {
   x = 1
} else {
   x = 0
}

is better readable than

x = useOne ? 1 : 0

func Transpose

func Transpose[C any](data [][]C) [][]C

Transpose does a matrix transpose Example:

Transpose([][]int{
	{1, 2, 3},
	{4, 5, 6},
})

returns

[][]int{
	{1, 4},
	{2, 5},
	{3, 6},
}

In case either dimension is 0, an empty slice is returned. (A matrix with zero columns – transposed – will have zero rows. Thus, the result is an empty slice. A matrix with zero rows cannot be said to have non-zero columns. So, also in this case an empty slice is returned. This is due to the fact that the dimensions of the matrix are not held separately.)

func WriteBytes added in v2.0.2

func WriteBytes(filename string, content []byte) error

WriteBytes writes binary content to a file.

func WriteJsonFile

func WriteJsonFile(filename string, data any)

WriteJsonFile writes an object into a JSON file

func WriteLines

func WriteLines(filename string, lines []string)

WriteLines writes a slice of stings as text file

Types

type Integer

type Integer interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64
}

type Number

type Number interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64 | ~float32 | ~float64
}

Number should cover all types for which Go offers basic arithmetic operations

type Set

type Set[C comparable] map[C]struct{}

Set is a set of objects in the mathematical sense. I.e. it is unsorted and can contain each element only once. It provides expected methods such as intersections, unions, and information functions.

Create a set from a slice using MakeSet() A set can be transformed into a slice using ToSlice()

There are no .Empty or .Len functions, as this can be done via the regular len(...) function. .Equal can be done via reflect.DeepEqual()k

func Intersection

func Intersection[C comparable](set1 Set[C], set2 Set[C]) Set[C]

Intersection (similar to [Intersect]) delivers the intersection of two sets. The original sets are not changed. Example:

Intersection(MakeSet(1, 2), MakeSet([]int{2, 3}))

returns {2}

func MakeSet

func MakeSet[C comparable](input ...C) Set[C]

MakeSet creates a set from a slice, e.g.

MakeSet(2,4,6,2)

creates the set {2,4,6}.

func MapSet

func MapSet[A comparable, B comparable](s Set[A], f func(A) B) Set[B]

MapSet maps a function to all elements of a set. It returns a new set, containing all function results. The new set might be smaller than the original set. Example:

MapSet(MakeSet(1, 2, 3), func(a int) int { return 2 * a })
MapSet(MakeSet(-1, 0, 1), Abs)

return {2, 4, 6} resp. {0, 1}

func SetDifference

func SetDifference[C comparable](set1 Set[C], set2 Set[C]) Set[C]

SetDifference (similar to [SubtractSet]) delivers the set difference of two sets. The original sets are not changed. Example:

SetDifference(MakeSet(1, 2), MakeSet([]int{2, 3}))

returns {1}

func Union

func Union[C comparable](set1 Set[C], set2 Set[C]) Set[C]

Union (similar to [AddSet]) returns the union of two sets. The original sets are not changed. Example:

Union(MakeSet(1, 2), MakeSet([]int{2, 3}))

returns {1,2,3}

func (Set[C]) Add

func (s Set[C]) Add(elts ...C) Set[C]

Add adds one or more elements to a set. The set is altered and it is returned. It's ok to add an already existing element (the set is not changed). Examples:

MakeSet(1, 2, 3).Add(4)
MakeSet(1, 2, 3).Add(2,3,4,5)

return {1,2,3,4} resp. {1,2,3,4,5}

func (Set[C]) AddSet

func (s Set[C]) AddSet(secondSet Set[C]) Set[C]

AddSet (similar to Union) adds elements from another set to a set. It alters and returns the given set.

MakeSet(1, 2, 3).AddSet(MakeSet([]int{3, 4})

returns the set {1, 2, 3, 4}

func (Set[C]) Contains

func (s Set[C]) Contains(elt C) bool

Contains checks if a given set contains an element Example:

MakeSet(1, 2, 3).Contains(1)

returns true

func (Set[C]) Copy

func (s Set[C]) Copy() Set[C]

Copy copies a set. It copies only the set itself, not the values. (I.e., it does /not/ perform a deep copy.)

func (Set[C]) Delete

func (s Set[C]) Delete(elt C) Set[C]

Delete deletes one element from a set. The set is altered and it is returned. It's ok to delete an element that does not exist (the set is not changed). Examples:

MakeSet(1, 2, 3).Delete(2)

returns {1,3}

func (Set[C]) Every

func (s Set[C]) Every(pred func(C) bool) bool

Every returns true if `pred` returns true for every value of a sequence. Example:

MakeSet(2, 3, 4).Every(func(n int) bool { return n > 1 }) // returns true
MakeSet(2, 0, 4).Every(func(n int) bool { return n > 1 }) // returns false
MakeSet[int]().Every(func(n int) bool { return n > 1 })   // returns true

func (Set[C]) GetArbitraryElement

func (s Set[C]) GetArbitraryElement() C

GetArbitraryElement returns an arbitrary element from a set. It panics when called on an empty set. Example:

MakeSet(1, 2).GetArbitraryElement()

returns 1 or 2

func (Set[C]) Intersect

func (s Set[C]) Intersect(secondSet Set[C]) Set[C]

Intersect (similar to Intersection) removes elements /not/ contained in another set. It alters and returns the given set.

MakeSet(1, 2).Intersect(MakeSet([]int{2, 3})

returns the set {2}

func (Set[C]) IsSubsetOf

func (s Set[C]) IsSubsetOf(super Set[C]) bool

IsSubsetOf checks if the set is a subset of (or equal to) another set. Example:

MakeSet(1, 2, 3).IsSubsetOf([]int{1, 2})

returns true

func (Set[C]) IsSupersetOf

func (s Set[C]) IsSupersetOf(sub Set[C]) bool

IsSupersetOf checks if the set is a superset of (or equal to) another set. Example:

MakeSet(1, 2).IsSupersetOf([]int{1, 2, 3})

returns true

func (Set[C]) Iter added in v2.0.4

func (s Set[C]) Iter() iter.Seq[C]

Iter returns an iterator to loop across the elements of the set. Example:

for i := range MakeSet(1,2,1).Iter() {
     fmt.Println(i)
}

will print the numbers 1 and 2 (in arbitrary order).

func (Set[C]) Len added in v2.0.4

func (s Set[C]) Len() int

func (Set[C]) Some

func (s Set[C]) Some(pred func(C) bool) bool

Some returns true if `pred` returns true for at least one value of a set.

MakeSet(2, 3, 4).Every(func(n int) bool { return n > 1 }) // returns false
MakeSet(2, 0, 4).Every(func(n int) bool { return n > 1 }) // returns true
MakeSet[int]().Every(func(n int) bool { return n > 1 })   // returns false

func (Set[C]) SubtractSet

func (s Set[C]) SubtractSet(secondSet Set[C]) Set[C]

SubtractSet (similar to SetDifference) removes elements from another set to a set. It alters and returns the given set.

MakeSet(1, 2).SubtractSet(MakeSet([]int{2, 3})

returns the set {1}

func (Set[C]) ToSlice

func (s Set[C]) ToSlice() []C

ToSlice turns a set into a slice of its elements. The order of the elements is undefined.

MakeSet(1, 2).ToSlice()

returns []int{1,2} or []int{2,1}

Jump to

Keyboard shortcuts

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