Collection of generics-related utility functions, slice/map/channel manipulation and some parallel processing.
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
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]
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
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]
CompareSliceSet
- check whether slices have same elements regardless of orderSliceMap
- Convert slice to map using function to get the key.[]Struct{} -> f(s)K -> map[Struct.key]Struct
being the common usageSliceMapFunc
- 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
- AsSliceDiff
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 sliceSliceDedupe
- remove duplicates fromcomparable
slice.[]T -> []T
SliceDedupeFunc
- remove duplicates fromany
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
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 asMap
but function can return error that will stop the loop and propagate it out.T1... -> ([]T2,err)
MapSliceErr
- Same asMapSlice
but function can return error that will stop the loop and propagate it out.T1... -> ([]T2,err)
MapSliceSkip
- Same asMapSlice
but function can return true in second argument to skip the entry.[]T1 -> []T2
MapSliceErrSkip
- Same asMapSliceErr
butErrSkip
error type can be used to skip entry instead of erroring out.[]T1 -> ([]T2,err)
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)
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
WorkerPool
- spawn x goroutines with workers and return after input channel is closed and all requests are parsed. Optionally close outputWorkerPoolBackground
- 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 withbool{true}
when the processing ends.WorkerPoolDrain
- spawn x goroutines that will run a function on the channel element without returning anythingWorkerPoolAsync
- 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
ParallelMap
- likeMap
but runs function in parallel up to specified number of goroutines. Ordered.ParallelMap
- likeMapMap
but runs function in parallel up to specified number of goroutines. Ordered.ParallelMapSlice
- likeMapSlice
but runs function in parallel up to specified number of goroutines. Ordered.ParallelMapSliceChan
- runs slice elements thru function and sends it to channelParallelMapSliceChanFinisher
- runs slice elements thru function and sends it to channel. Returnsfinisher chan(bool){true}
that will return singletrue
message when all workers finish and close it
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
- asAsyncPipe
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
Retry
- retry function X timesRetryAfter
- retry with timeout, minimal, and maximal interval between retries.Try
- tries each function in slice till first success
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
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 intsMin
Max
Avg
AvgF64
- average with final input calculated as float64. Addition is still in sourceAvgF64F64
- average with float64 accumulator. Use if you want to avoid overflow on small int typeMedian
MedianF64
- median with final division using float64 type to avoid overflows
Number
- any basic numeric typesValueIndex
- represents slice element with indexKeyValue
- represents map key/value pair
Must
- Turn error into panic, returning non-err argumentsIgnoreErr
- Ignores error, returning default type value if error is passed
No API changes to existing functions AP will be made in 1.x.x releases