diff --git a/maputils/mapUtils.go b/maputils/mapUtils.go index 38bae9d..3565525 100644 --- a/maputils/mapUtils.go +++ b/maputils/mapUtils.go @@ -73,6 +73,8 @@ func CompareMap[K, V comparable](a, b map[K]V) bool { return true } +// Compact reduces the keys and values of a map down into one value each. +// The starting value for each is the default value of that type. func Compact[K comparable, V any]( m map[K]V, compactor func(accK K, accV V, nextK K, nextV V) (K, V), diff --git a/sliceutils/sliceUtils.go b/sliceutils/sliceUtils.go index 26e45b9..8b427e9 100644 --- a/sliceutils/sliceUtils.go +++ b/sliceutils/sliceUtils.go @@ -1,7 +1,7 @@ // Package sliceutils contains various generic functions for applying an operation across an entire slice package sliceutils -// MapS applies a given function to every element of a slice. +// Map applies a given function to every element of a slice. // The return type may be different from the initial type of the slice. func Map[T any, M any](arr []T, apply func(T) M) []M { n := make([]M, len(arr)) @@ -73,6 +73,7 @@ func CompareUnordered[T comparable](a, b []T) bool { return hits == len(a) } +// Returns whether b exists inside a using a simple == comparison func Contains[T comparable](a []T, b T) bool { for _, v := range a { if v == b { @@ -82,6 +83,7 @@ func Contains[T comparable](a []T, b T) bool { return false } +// Returns whether the given function f returns true for any element in a func ContainsFunc[T any](a []T, f func(t T) bool) bool { for _, v := range a { if f(v) { @@ -91,6 +93,8 @@ func ContainsFunc[T any](a []T, f func(t T) bool) bool { return false } +// Compact the slice a using the compactor function. +// For the first call, the accumulator argument will be the default value func Compact[T any](a []T, compactor func(acc T, next T) T) T { var acc T for _, v := range a { @@ -98,3 +102,28 @@ func Compact[T any](a []T, compactor func(acc T, next T) T) T { } return acc } + +// Returns a channel that all elements in a will be written to in order. +// Once all values of a have been sent, the channel will be closed. +// The channel must be fully consumed until closed. Otherwise a goroutine will be leaked +func ToChannel[T any](a []T) chan T { + c := make(chan T) + go func() { + for _, v := range a { + c <- v + } + close(c) + }() + + return c +} + +// FromChannel reads from a channel until closed, appending every element to a slice. +// If you do not know how many elements to expect, use an expectedSize of 0 +func FromChannel[T any](c chan T, expectedSize uint) []T { + a := make([]T, expectedSize) + for v := range c { + a = append(a, v) + } + return a +}