goneric

package module
v1.3.0 Latest Latest
Warning

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

Go to latest
Published: Feb 24, 2025 License: MIT Imports: 3 Imported by: 17

README

go report card test status codecov MIT license Go.Dev reference

Goneric

Collection of generics-related utility functions, slice/map/channel manipulation and some parallel processing.

Conventions

If not specified the returning value will be at least initiated to be empty, not nil.

Functions returning stuff like map[key]boolean (using map as set) set the boolean value to true because m["nonexistent_key"] == false

Naming function goes in order of operation_group, input type, modifier/output with ones irrelevant skipped. Functions where it is sensible to have option to close channel should have that as last optional argument. There are few exceptions for convenience, like variadic Map.

If possible, sensible, functions that take function parameter should have function as first parameter.

Channel-operating function in general should accept channel as parameter; the ones returning a channel should be under Gen* hierarchy

Examples

Get the list of elements that differ between slices of different types
data1 := []string{"1", "2", "3", "4", "5"}
data2 := []float32{1, 7, 3, 4}
stringToInt := func(s string) int {
	i, _ := strconv.Atoi(s)
	return i
}
floatToInt := func(f float32) int {
	return int(f)
}
left, right := SliceDiffFunc(data1, data2, stringToInt, floatToInt)
fmt.Printf("left: %T%+v right: %T%+v", left, left, right, right)
// left: []string[2 5] right: []float32[7]
Convert every string to float, exit on first error
in := []string{"1", "2.2", "3", "cat","5"}
out, err := goneric.MapSliceErr(func(s string) (float64, error) {
	return strconv.ParseFloat(s, 64)
}, in)
fmt.Printf("%+v, err: %s", out, err)
// [1 2.2 3], err: strconv.ParseFloat: parsing "cat": invalid syntax
Convert every string to float, skip entries with error
in := []string{"1", "2.2", "3", "cat", "5"}
out := goneric.MapSliceSkip(func(s string) (float64, bool) {
	f, err := strconv.ParseFloat(s, 64)
	return f, err != nil
}, in)
fmt.Printf("%+v", out)
// [1 2.2 3 5]
Run every element of map thru function in parallel, creating new map, at max concurrency of 2 goroutines
data := map[string]int{
	"a": 99,
	"b": 250,
	"c": 30,
	"d": 9,
}
mappedData := goneric.ParallelMapMap(func(k string, v int) (string, string) {
	time.Sleep(time.Millisecond * time.Duration(v))
	return k, fmt.Sprintf("0x%02x", v)
}, 2, data)
fmt.Printf("%+v", mappedData)
// map[a:0x63 b:0xfa c:0x1e d:0x09]

Functions

Slice
  • CompareSliceSet - check whether slices have same elements regardless of order
  • SliceMap - Convert slice to map using function to get the key. []Struct{} -> f(s)K -> map[Struct.key]Struct being the common usage
  • SliceMapFunc - Convert slice to map using function to return key and value. []Struct{} -> f(s)(K,V) -> map[K]V
  • SliceMapSet - Convert slice to set-like map. []K -> map[K]bool{true}
  • SliceMapSetFunc - Convert slice to set-like map via helper function. []T -> map[func(T)Comparable]bool{true}
  • SliceDiff - return difference between 2 slices of same comparable type, in form of 2 variables where first have elements that are only in first set, and second elements only in second set. ([]T, []T) -> (leftOnly []T, rightOnly []T)
  • SliceDiffFunc - As SliceDiff but type of slice is irrelevant, via use of conversion function that converts it into comparable type. ([]T1,[]T2) -> (leftOnly []T1, rightOnly []T2)
  • SliceIn - Check whether value is in slice
  • SliceDedupe - remove duplicates from comparable slice. []T -> []T
  • SliceDedupeFunc - remove duplicates from any slice via conversion function. []T -> []T
  • SliceReverse - reverses the order of elements in slice and returns reversed copy, []T -> []T
  • SliceReverseInplace - reverses the order of elements in slice in-place.
  • FirstOrEmpty - return first element or empty value. []T -> T
  • LastOrEmpty - return last element or empty value. []T -> T
  • FirstOrEmpty - return first element or passed "default" value. []T -> T
  • LastOrEmpty - return last element or passed "default" value. []T -> T
Map
  • MapMap - Map one map to another using a function. map[K1]V1 -> map[K2]V2
  • MapMapInplace - Map one map to another using a function, filling existing passed map. (in map[K1]V1, out map[K2]V2)
  • Map - Map variadic input thru function. T1... -> []T2
  • MapSlice - Map slice thru function. []T1 -> []T2
  • MapSliceKey - Convert map to slice of its keys. map[K]V -> []K
  • MapSliceValue - Convert map to slice of its values. map[K]V -> []V
  • MapErr - Same as Map but function can return error that will stop the loop and propagate it out. T1... -> ([]T2,err)
  • MapSliceErr - Same as MapSlice but function can return error that will stop the loop and propagate it out. T1... -> ([]T2,err)
  • MapSliceSkip - Same as MapSlice but function can return true in second argument to skip the entry. []T1 -> []T2
  • MapSliceErrSkip - Same as MapSliceErr but ErrSkip error type can be used to skip entry instead of erroring out. []T1 -> ([]T2,err)
  • MapToSlice - use f(K,V)V2 to generate slice from map. map[K]V -> []V2
  • MapToSliceSorted - use f(K,V)V2 to generate slice from map, elements are parsed in order sorted via sortedFuncLess(left K, right K). map[K]V -> sort(K,K) -> []V2
Filter
  • FilterMap - Filter thru a map using a function. map[K]V -> map[K]V
  • FilterSlice - Filter thru a slice using a function. []T -> []T
  • FilterChan - Filter thru a channel using a function. in chan T -> out chan T
  • FilterChanErr - Filter thru a channel using a function, with separate output channel for that function errors. in chan T -> (out chan T,err chan error)
Channel tools
  • ChanGen - Feed function output to passed channel in a loop. (f()T, chan T)
  • ChanGenN - Feed function output to passed channel in a loop N times, optionally close it. (f()T, count, chan T)
  • ChanGenCloser - Use function to pass generated messages to channel, stop when closer function is called, (f()T, chan T) -> chan closeChannel
  • ChanToSlice - Loads data to slice from channel until channel is closed. chan T -> []T
  • ChanToSliceN - Loads data to slice from channel to at most N elements. (chan T,count) -> []T
  • ChanToSliceNTimeout - Loads data to slice from channel to at most N elements or until timeout passes. (chan T,count,timeout) -> []T
  • SliceToChan - Sends slice to passed channel in background, optionally closes it. []T -> chan T
Worker
  • WorkerPool - spawn x goroutines with workers and return after input channel is closed and all requests are parsed. Optionally close output
  • WorkerPoolBackground - spawn x goroutines with workers in background and returns output channel. Optionally close output.
  • WorkerPoolFinisher - spawn x goroutines with workers in background, returns finisher channel that signals with bool{true} when the processing ends.
  • WorkerPoolDrain - spawn x goroutines that will run a function on the channel element without returning anything
  • WorkerPoolAsync - function will run x goroutines for worker in the background and return a function that enqueues job and returns channel with result of that job, allowing to queue stuff to run in background conveniently
Parallel
  • ParallelMap - like Map but runs function in parallel up to specified number of goroutines. Ordered.
  • ParallelMap - like MapMap but runs function in parallel up to specified number of goroutines. Ordered.
  • ParallelMapSlice - like MapSlice but runs function in parallel up to specified number of goroutines. Ordered.
  • ParallelMapSliceChan - runs slice elements thru function and sends it to channel
  • ParallelMapSliceChanFinisher - runs slice elements thru function and sends it to channel. Returns finisher chan(bool){true} that will return single true message when all workers finish and close it
Async
  • Async - run function in background goroutine and return result as a channel. func()T -> chan T
  • AsyncV - run functions in background goroutine and return result as a channel, then close it. funcList... -> chan T
  • AsyncVUnpanic - run function in background goroutine and return result as a channel, then close it, ignoring every panic. funcList... -> chan T
  • AsyncPipe - run function in background, taking and returning values to pipe. Designed to be chained. (in chan T1, func(T1)T2) -> chan T2
  • AsyncOut - as AsyncPipe but takes output channel as argument .(in chan T1, func(T1)T2, chan T2)
  • AsyncIn - converts value into channel with that value. T -> chan T
(Re)Try
  • Retry - retry function X times
  • RetryAfter - retry with timeout, minimal, and maximal interval between retries.
  • Try - tries each function in slice till first success
Generators

Generator functions always return generated values. For ones that operate on passed on types look at Type*Gen* functions like SliceGen

  • GenSlice - generate slice of given length via function. func(idx int) T -> []T
  • GenMap - generate Map of given length via function. func(idx int) K,V -> map[K]V
  • GenChan - returns channel fed from generator function ad infinitum. func() K -> chan T
  • GenChanN - returns channel fed from generator function N times. func() K -> chan T
  • GenChanNCloser - returns channel fed from generator that returns closer() function that will stop generator from running.func() K -> (chan T,func closer())
  • GenSliceToChan - returns channel fed from slice, optionally closes it, []K -> chan T
Math

Not equivalent of math library, NaN math is ignored, zero length inputs might, sanitize your inputs.

Results unless specified otherwise will follow math of type, so median of []int{8,9} will be int{8} coz of rounding.

  • Sum
  • SumF64 - sum returning float64, for summing up small ints
  • Min
  • Max
  • Avg
  • AvgF64 - average with final input calculated as float64. Addition is still in source
  • AvgF64F64 - average with float64 accumulator. Use if you want to avoid overflow on small int type
  • Median
  • MedianF64 - median with final division using float64 type to avoid overflows

Types

  • Number - any basic numeric types
  • ValueIndex - represents slice element with index
  • KeyValue - represents map key/value pair

Miscellaneous

  • Must - Turn error into panic, returning non-err arguments
  • IgnoreErr - Ignores error, returning default type value if error is passed

Current project state

No API changes to existing functions AP will be made in 1.x.x releases

Analytics

  • Coverage map

    img

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Async added in v0.1.7

func Async[T1 any](f func() T1) chan T1

Async runs a function in goroutine and returns pipe with result

Example
// make our conversion output channel
out := make(chan string, 1)

// queue first element
AsyncOut(
	AsyncPipe(
		AsyncIn(time.Unix(123456789, 0)),
		func(in time.Time) (out string) { return in.Format("2006-01-02") },
	),
	func(in string) (out string) {
		// just to make sure that one comes second
		time.Sleep(time.Millisecond * 10)
		return "date: " + in
	},
	out)
// queue second element
AsyncOut(
	AsyncPipe(
		AsyncPipe(
			AsyncIn(12345678),
			func(in int) (out time.Time) { return time.Unix(int64(in), 0) },
		),
		func(t time.Time) string { return t.Format("2006-01-02") },
	),
	func(in string) (out string) { return "date: " + in },
	out)
fmt.Printf("%s %s",
	<-out,
	<-out,
)
Output:

date: 1970-05-23 date: 1973-11-29

func AsyncIn added in v0.1.7

func AsyncIn[T1 any](in T1) (out chan T1)

AsyncIn turns value into channel with value

func AsyncOut added in v0.1.7

func AsyncOut[T1, T2 any](in chan T1, f func(T1) T2, out chan T2)

AsyncOut takes value and feeds it to function returning asynchronously to channel

func AsyncPipe added in v0.1.7

func AsyncPipe[T1, T2 any](in chan T1, f func(T1) T2) chan T2

AsyncPipe runs a function in goroutine from input channel and returns pipe with result

func AsyncV added in v0.1.8

func AsyncV[T1 any](funcList ...func() T1) chan T1

AsyncV runs a number of functions in goroutine and returns pipe with result then closes after goroutines finish order is not guaranteed

func AsyncVUnpanic added in v0.1.8

func AsyncVUnpanic[T1 any](funcList ...func() T1) chan T1

AsyncVUnpanic runs a number of functions in goroutine and returns pipe with result then closes after goroutines finish order is not guaranteed panics are suppressed

func Avg added in v0.1.4

func Avg[T Number](n ...T) (avg T)

func AvgF64 added in v0.1.4

func AvgF64[T Number](n ...T) (avg float64)

AvgF64 calculates average with final division using float64 type int overflow can still happen

func AvgF64F64 added in v0.1.4

func AvgF64F64[T Number](n ...T) (avg float64)

AvgF64F64 calculates average after converting any input to float64 to avoid integer overflows

func ChanGen added in v0.1.4

func ChanGen[T any](genFunc func() T, ch chan T)

ChanGen sends function output to provided channel

func ChanGenCloser added in v0.1.4

func ChanGenCloser[T any](genFunc func() T, ch chan T) (closer func(closeChannel ...bool))

ChanGenCloser generates a channel that is fed from function results. Running closer func will stop it. Closing is asynchronous and number of events in flight depends on channel size so don't rely on stooping after exact number of calls, If you need synchronous close here you're probably doing something wrong

func ChanGenN added in v0.1.8

func ChanGenN[T any](count int, genFunc func(idx int) T, out chan T, closeOutputChan ...bool) (finished chan bool)

ChanGenN runs function n times and sends the result to the provided channel resulting channel will be sent `true` when the function finishes last send Function gets id of element starting from 0. setting optional argument to true will close the channel after finishing

func ChanToSlice added in v0.1.4

func ChanToSlice[T any](inCh chan T) []T

ChanToSlice loads channel messages to slice until channel is closed

func ChanToSliceN added in v0.1.4

func ChanToSliceN[T any](inCh chan T, n int) []T

ChanToSliceN loads up to n elements from to slice to channel

func ChanToSliceNTimeout added in v0.1.8

func ChanToSliceNTimeout[T any](inCh chan T, n int, timeout time.Duration) []T

ChanToSliceNTimeout loads up to n elements from to slice to channel or up until timeout expires

func CompareSliceSet

func CompareSliceSet[T comparable](v1 []T, v2 []T) bool

CompareSliceSet compares 2 slices and returns true if all elements of slice v1 are the same as in v2 order does not matter, the duplicates are ignored

func FilterChan added in v0.1.3

func FilterChan[T any](filterFunc func(T) bool, in chan T) (out chan T)

FilterChan filters elements going thru a channel close is propagated

func FilterChanErr added in v0.1.4

func FilterChanErr[T any](filterFunc func(T) (bool, error), in chan T) (out chan T, errCh chan error)

FilterChanErr filters elements going thru channel, redirecting errors to separate channel both channels need to be read or else it will stall close is propagated

func FilterMap added in v0.1.2

func FilterMap[K comparable, V any](filterFunc func(k K, v V) (accept bool), in map[K]V) (out map[K]V)

FilterMap runs function on every element of map and adds it to result map if it returned true

func FilterSlice added in v0.1.2

func FilterSlice[V any](filterFunc func(idx int, v V) (accept bool), in []V) (out []V)

FilterSlice runs function on every element of slice and adds it to result slice if it returned true

func FirstOrDefault added in v0.1.8

func FirstOrDefault[T any](slice []T, def T) (out T)

FirstOrDefault returns first element of slice or passed default value

func FirstOrEmpty added in v0.1.8

func FirstOrEmpty[T any](slice []T) (out T)

FirstOrEmpty returns first element of slice or empty/default type

func GenChan added in v0.1.8

func GenChan[T any](genFunc func() T) chan T

GenChan generates a channel that is fed from function results

func GenChanCloser added in v0.1.8

func GenChanCloser[T any](genFunc func() T) (out chan T, closer func(closeChannel ...bool))

func GenChanN added in v0.1.8

func GenChanN[T any](genFunc func(idx int) T, count int, closeOutputChan ...bool) (ch chan T)

GenChanN generates channel that will run function n times and send result to channel, then close it Function gets id of element starting from 0. setting optional argument to true will close the channel after finishing

func GenMap added in v0.1.8

func GenMap[K comparable, V any](count int, f func(idx int) (K, V)) (out map[K]V)

GenMap generates a map of given size based on passed function. Function gets id of element starting from 0.

func GenSlice added in v0.1.8

func GenSlice[T any](count int, f func(idx int) T) (out []T)

GenSlice generates a slice of given length based on passed function. Function gets id of element starting from 0.

func GenSliceToChan added in v0.1.8

func GenSliceToChan[T any](in []T, closeOutputChan ...bool) (out chan T)

GenSliceToChan returns channel with background goroutine feeding it data from slice

Example
// jobs to do
input := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
output := ChanToSlice( // make slice out of channel
	WorkerPoolBackground( // that we got out of worker
		GenSliceToChan(input, true), // that got fed input from slice via channel
		func(v int) float64 {
			// pretend we have some work
			time.Sleep(time.Millisecond*20 + time.Duration(rand.Int31n(20)))
			return float64(v) * 1.5
		},
		16, true, // in parallel
	))
fmt.Printf("%+v->(1.5x)->%+v", Sum(input...), Sum(output...))
Output:

55->(1.5x)->82.5

func IgnoreErr added in v1.1.0

func IgnoreErr[T any](in T, err error) (out T)

IgnoreErr takes any value, and on error returns the default value You should probably not use it...

func LastOrDefault added in v0.1.8

func LastOrDefault[T any](slice []T, def T) (out T)

LastOrDefault returns last element of slice or passed default value

func LastOrEmpty added in v0.1.8

func LastOrEmpty[T any](slice []T) (out T)

LastOrEmpty returns last element of slice or empty/default type

func Map

func Map[T1, T2 any](mapFunc func(v T1) T2, slice ...T1) []T2

Map maps the list of variadic(...) values via function. It is provided as convenience, MapSlice() should be used when you have incoming slice

func MapErr

func MapErr[T1, T2 any](mapFunc func(v T1) (T2, error), slice ...T1) (out []T2, err error)

MapErr maps the list of variadic(...) values via function. and returns on first error Returns slice with elements that didn't return error before the failure so index of the first element in error is essentially `slice[len(out)]`

func MapMap added in v0.1.9

func MapMap[K1, K2 comparable, V1, V2 any](mapFunc func(k K1, v V1) (K2, V2), in map[K1]V1) (out map[K2]V2)

MapMap runs every map element thru function that returns new key and value, and returns that in another map. Types can vary between in and out.

func MapMapInplace added in v0.1.9

func MapMapInplace[K1, K2 comparable, V1, V2 any](mapFunc func(k K1, v V1) (K2, V2), in map[K1]V1, out map[K2]V2)

MapMapInplace runs every map element thru function that returns new key and value, and puts it into existing map. Types can vary between in and out.

func MapSlice

func MapSlice[T1, T2 any](mapFunc func(v T1) T2, slice []T1) []T2

MapSlice maps slice using provided function

Example
out := MapSlice(
	func(i int) string { return fmt.Sprintf("-=0x%02x=-", i) },
	MapSlice(
		func(i int) int { return i + 1 },
		MapSlice(
			func(i int) int { return i * i },
			GenSlice(10, func(idx int) int { return idx }),
		),
	),
)
fmt.Printf("%+v", out)
Output:

[-=0x01=- -=0x02=- -=0x05=- -=0x0a=- -=0x11=- -=0x1a=- -=0x25=- -=0x32=- -=0x41=- -=0x52=-]

func MapSliceErr

func MapSliceErr[T1, T2 any](mapFunc func(v T1) (T2, error), slice []T1) (out []T2, err error)

MapSliceErr maps slice using provided function, returning first error Returns slice with elements that didn't return error

func MapSliceErrSkip added in v0.1.3

func MapSliceErrSkip[T1, T2 any](mapFunc func(v T1) (T2, error), slice []T1) (out []T2, err error)

MapSliceErrSkip maps slice using provided function, allowing to skip entries by returning ErrSkip Returns on first non `ErrSkip` error

func MapSliceKey

func MapSliceKey[K comparable, V any](in map[K]V) (out []K)

MapSliceKey returns keys of a map in slice

func MapSliceSkip added in v0.1.3

func MapSliceSkip[T1, T2 any](mapFunc func(v T1) (T2, bool), slice []T1) (out []T2)

MapSliceSkip maps slice using provided function, allowing to skip entries by returning true Returns slice with elements that didn't return true

func MapSliceValue

func MapSliceValue[K comparable, V any](in map[K]V) (out []V)

MapSliceValue returns values of a map in slice

func MapToSlice added in v0.1.4

func MapToSlice[K1 comparable, V any, V2 any](f func(k K1, v V) V2, in map[K1]V) (out []V2)

MapToSlice converts map into slice via specified function

func MapToSliceSorted added in v1.3.0

func MapToSliceSorted[K1 comparable, V any, V2 any](
	f func(k K1, v V) V2,
	sortFuncLess func(left K1, right K1) bool,
	in map[K1]V,
) (out []V2)

MapToSliceSorted converts map into slice via specified function

func Max added in v0.1.4

func Max[T Number](n ...T) (max T)

Max returns biggest number will panic on empty

func Median added in v0.1.4

func Median[T Number](n ...T) (median T)

func MedianF64 added in v0.1.4

func MedianF64[T Number](n ...T) (median float64)

MedianF64 calculates median with final division using float64 type

func Min added in v0.1.4

func Min[T Number](n ...T) (min T)

Min returns smallest number will panic on empty

func Must added in v1.1.0

func Must[T any](in T, err error) (out T)

Must takes any value and error, returns the value and panics if error happens.

func ParallelMap added in v0.1.1

func ParallelMap[T1, T2 any](mapFunc func(T1) T2, concurrency int, slice ...T1) []T2

ParallelMapSlice takes variadic argument and runs all of them thru function in parallel, up to `concurrency` goroutines Order of elements in slice is kept

func ParallelMapMap added in v0.1.10

func ParallelMapMap[K1, K2 comparable, V1, V2 any](
	mapFunc func(k K1, v V1) (K2, V2),
	concurrency int,
	in map[K1]V1,
) map[K2]V2

ParallelMapMap takes map and runs each element thru function in parallel, storing result in a map

func ParallelMapSlice added in v0.1.1

func ParallelMapSlice[T1, T2 any](mapFunc func(T1) T2, concurrency int, slice []T1) []T2

ParallelMapSlice takes slice and runs it thru function in parallel, up to `concurrency` goroutines Order of elements in slice is kept

Example
data := []string{"1", "3", "2", "7", "9", "12"}
mappedData := ParallelMapSlice(
	// function used to map
	func(v string) int {
		time.Sleep(time.Millisecond * time.Duration(rand.Int31n(10)))
		i, _ := strconv.Atoi(v)
		return i
	},
	3, // run it at least this many times
	data)
// order stays
fmt.Printf("%T%+v\n%T%+v", data, data, mappedData, mappedData)
Output:

[]string[1 3 2 7 9 12]
[]int[1 3 2 7 9 12]

func ParallelMapSliceChan added in v0.1.4

func ParallelMapSliceChan[T1, T2 any](mapFunc func(T1) T2, concurrency int, slice []T1) chan T2

ParallelMapSliceChan feeds slice to function in parallel and returns channels with function output channel is closed when function finishes. Caller should close input channel when it finishes sending or else it will leak goroutines

func ParallelMapSliceChanFinisher added in v0.1.4

func ParallelMapSliceChanFinisher[T1, T2 any](mapFunc func(T1) T2, concurrency int, slice []T1) (chan T2, chan bool)

ParallelMapSliceChanFinisher feeds slice to function in parallel and returns channels with function output channel is closed when function finishes. Caller should close input channel when it finishes sending or else it will leak goroutines Second channel will return true (and then be closed) when the worker finishes parsing

func Retry added in v0.1.8

func Retry[T any](n int, f func() (T, error)) (T, error)

Retry retries function that returns error up to n times

func RetryAfter added in v0.1.8

func RetryAfter[T any](
	min_interval,
	max_interval,
	total_timeout time.Duration,
	f func() (T, error),
) (T, error)

RetryAfter retries function till it returns without error, first after min_interval, then with increasing intervals up to max_interval with last retry happening near total_timeout Intended use is to be able to say "retry for 10 minutes, at the very least every minute, but not shorter than 10 seconds to account for TCP retransmissions"

func SliceDedupe added in v0.1.8

func SliceDedupe[T comparable](slice []T) (out []T)

SliceDedupe removes duplicates

func SliceDedupeFunc added in v0.1.8

func SliceDedupeFunc[T any, C comparable](slice []T, convert func(T) C) (out []T)

SliceDedupeFunc removes duplicates with function to convert the value to comparable

func SliceDiff

func SliceDiff[T comparable](v1 []T, v2 []T) (inLeft []T, inRight []T)

SliceDiff compares two slices of comparable values and returns slice of elements that are only in first/left element and ones that are only in right element Duplicates are ignored. `([]T, []T) -> (leftOnly []T, rightOnly []T)`

func SliceDiffFunc

func SliceDiffFunc[T1 any, T2 any, Z comparable](
	v1 []T1,
	v2 []T2,
	convertV1 func(T1) Z,
	convertV2 func(T2) Z,
) (inLeft []T1, inRight []T2)

SliceDiffFunc compares two slices of any value using one conversion function per type to convert it into conmparables returns slice of elements that are only in first/left element and ones that are only in right element. Duplicates are ignored. ([]DataT,[]ReturnT) -> (leftOnly []DataT, rightOnly []ReturnT)

Example
data1 := []string{"1", "2", "3", "4", "5"}
data2 := []float32{1, 7, 3, 4}
stringToInt := func(s string) int {
	i, _ := strconv.Atoi(s)
	return i
}
floatToInt := func(f float32) int {
	return int(f)
}
left, right := SliceDiffFunc(data1, data2, stringToInt, floatToInt)
fmt.Printf("left: %T%+v right: %T%+v", left, left, right, right)
Output:

left: []string[2 5] right: []float32[7]

func SliceIn added in v0.1.5

func SliceIn[T comparable](slice []T, contains T) bool

SliceIn checks if slice contains a value. Value must be comparable

func SliceMap

func SliceMap[T any, M comparable](f func(T) M, a []T) map[M]T

SliceMap turn slice into a map via extracting key from it using helper function and setting the map value to that slice `[]Struct{} -> map[func(Struct)]Struct`

func SliceMapFunc added in v1.2.0

func SliceMapFunc[T any, K comparable, V any](mapFunc func(T) (K, V), slice []T) map[K]V

SliceMapFunc extracts key and value for map from slice using function `[]Any -> map[comparable K]V`

func SliceMapSet

func SliceMapSet[T comparable](a []T) (n map[T]bool)

SliceMapSet turns slice into map with key being slice elements and value being true boolean `[]Comparable -> map[Comparable]bool{true}`

func SliceMapSetFunc added in v0.0.3

func SliceMapSetFunc[T any, M comparable](mapFunc func(T) M, slice []T) (n map[M]bool)

SliceMapSetFunc turns slice into map with key being slice elements passed thru specified function and value being true boolean `[]Any -> map[func(Any)Comparable]bool{true}`

func SliceMapSkip

func SliceMapSkip[T any, Z comparable](comparable func(T) (comparable Z, skip bool), slice []T) (m map[Z]T)

SliceMapSkip works like `SliceMap` but allows slice->map function to skip elements via returning true to second argument `[]Struct{} -> map[func(Struct)]Struct`

Example
type CS struct {
	Name  string
	Value string
}
data := []CS{{Name: "t1", Value: "v1"}, {Name: "t2", Value: "v2"}, {Name: "t3", Value: "v3"}, {Name: "t4", Value: "v4"}}
sliceMap := SliceMapSkip(func(t CS) (string, bool) {
	if t.Name == "t2" {
		return t.Name, true
	} else {
		return t.Name, false
	}
}, data)
fmt.Printf("map from slice with skipped t2: [%+v]", sliceMap)
Output:

map from slice with skipped t2: [map[t1:{Name:t1 Value:v1} t3:{Name:t3 Value:v3} t4:{Name:t4 Value:v4}]]

func SliceReverse added in v1.2.0

func SliceReverse[T any](in []T) (out []T)

func SliceReverseInplace added in v1.2.0

func SliceReverseInplace[T any](out []T)

func SliceToChan added in v0.1.4

func SliceToChan[T any](in []T, out chan T, closeOutputChan ...bool)

SliceToChan feeds slice to channel

func Sum added in v0.1.4

func Sum[T Number](n ...T) (sum T)

func SumF64 added in v0.1.4

func SumF64[T Number](n ...T) (sum float64)

func Try added in v0.1.8

func Try[T any](f ...func() (T, error)) (out T, err error)

Try every function till one returns without error

func WorkerPool added in v0.1.1

func WorkerPool[T1, T2 any](input chan T1, output chan T2, worker func(T1) T2, concurrency int, closeOutputChan ...bool)

WorkerPool spawns `concurrency` goroutines eating from input channel and sending it to output channel caller should take care of closing input channel after it finished sending requests output channel will be closed after input is processed and closed optionally setting last option to true will make it close output channel

func WorkerPoolAsync added in v0.1.7

func WorkerPoolAsync[T1, T2 any](worker func(T1) T2, concurrency int) (async func(T1) chan T2, stop func())

WorkerPoolAsync returns a function that adds new job to queue and returns a channel with result, and function to stop worker

Example
// make our worker with function to mangle data
async, finish := WorkerPoolAsync(
	func(i int) string { return strconv.Itoa(i) },
	2)
defer finish() // close the pool once we stop using it
// queue some jobs
job1 := async(1)
job2 := async(2)
job3 := async(3)
job4 := async(4)
// all of those jobs are running in background at this point
// now get results
fmt.Printf("%s %s %s %s",
	<-job1,
	<-job3,
	<-job2,
	<-job4,
)
Output:

1 3 2 4

func WorkerPoolBackground added in v0.1.4

func WorkerPoolBackground[T1, T2 any](input chan T1, worker func(T1) T2, concurrency int, closeOutputChan ...bool) (output chan T2)

WorkerPoolBackground spawns `concurrency` goroutines eating from input channel and returns output channel with results optionally setting last option to true will make it close output channel

Example
out :=
	WorkerPoolBackground(
		WorkerPoolBackground(
			WorkerPoolBackground(
				GenChanN(func(idx int) int { return idx + 1 }, 3, true),
				func(i int) string { return strconv.Itoa(i) },
				4, true),
			func(s string) string { return ">" + s },
			5, true,
		),
		func(s string) string { return " |" + s },
		6, true)
sliceOut := ChanToSlice(out)
sort.Slice(sliceOut, func(i, j int) bool { return sliceOut[i] < sliceOut[j] })
fmt.Printf("%v", sliceOut)
Output:

[ |>1  |>2  |>3]

func WorkerPoolDrain added in v0.1.7

func WorkerPoolDrain[T1 any](worker func(T1), concurrency int, input chan T1) (finish chan bool)

WorkerPoolDrain runs function per input without returning anything. Goroutines close on channel close. returns finish channel that returns single boolean true after goroutines finish

func WorkerPoolFinisher added in v0.1.1

func WorkerPoolFinisher[T1, T2 any](input chan T1, output chan T2, worker func(T1) T2, concurrency int) chan bool

WorkerPoolFinisher runs WorkerPool in the background and returns channel that returns `true` then closes when workers finish

Types

type ErrSkip added in v0.1.3

type ErrSkip struct{}

func (ErrSkip) Error added in v0.1.3

func (v ErrSkip) Error() string

type KeyValue added in v0.1.10

type KeyValue[Key comparable, Value any] struct {
	K Key
	V Value
}

KeyValue represents map element

type Number added in v0.1.4

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

type Response added in v0.1.7

type Response[DataT, ReturnT any] struct {
	ReturnCh chan ReturnT
	Data     DataT
}

Response is used to pass data and channel to return value to worker

type ValueIndex added in v0.1.7

type ValueIndex[V any] struct {
	V   V
	IDX int
}

ValueIndex contains value with source index for ordered operation

Jump to

Keyboard shortcuts

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