diff --git a/README.md b/README.md index f49e380..ffbdf85 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,8 @@ fmt.Printf("%+v", mappedData) ### Slice * `CompareSliceSet` - check whether slices have same elements regardless of order -* `SliceMap` - Convert slice to map using function to get the key. `[]Struct{} -> map[Struct.key]Struct` being the common usage +* `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 diff --git a/async.go b/async.go index 5c3a803..0f9168b 100644 --- a/async.go +++ b/async.go @@ -69,7 +69,7 @@ func AsyncOut[T1, T2 any](in chan T1, f func(T1) T2, out chan T2) { }() } -//AsyncIn turns value into channel with value +// AsyncIn turns value into channel with value func AsyncIn[T1 any](in T1) (out chan T1) { out = make(chan T1, 1) out <- in diff --git a/filter.go b/filter.go index 645dd19..6f91b00 100644 --- a/filter.go +++ b/filter.go @@ -22,7 +22,7 @@ func FilterSlice[V any](filterFunc func(idx int, v V) (accept bool), in []V) (ou return out } -//FilterChan filters elements going thru a channel +// FilterChan filters elements going thru a channel // close is propagated func FilterChan[T any](filterFunc func(T) bool, in chan T) (out chan T) { out = make(chan T, 1) @@ -37,7 +37,7 @@ func FilterChan[T any](filterFunc func(T) bool, in chan T) (out chan T) { return out } -//FilterChanErr filters elements going thru channel, redirecting errors to separate channel +// 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 FilterChanErr[T any](filterFunc func(T) (bool, error), in chan T) (out chan T, errCh chan error) { diff --git a/parallel.go b/parallel.go index 4f0e558..dc085f2 100644 --- a/parallel.go +++ b/parallel.go @@ -10,7 +10,7 @@ func ParallelMap[T1, T2 any](mapFunc func(T1) T2, concurrency int, slice ...T1) return ParallelMapSlice(mapFunc, concurrency, slice) } -//ParallelMapSlice takes slice and runs it thru function in parallel, up to `concurrency` goroutines +// ParallelMapSlice takes slice and runs it thru function in parallel, up to `concurrency` goroutines // Order of elements in slice is kept func ParallelMapSlice[T1, T2 any](mapFunc func(T1) T2, concurrency int, slice []T1) []T2 { out := make([]T2, len(slice)) diff --git a/slice.go b/slice.go index bad5798..28ef88f 100644 --- a/slice.go +++ b/slice.go @@ -61,14 +61,26 @@ func SliceMapSet[T comparable](a []T) (n map[T]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 SliceMapSetFunc[T any, M comparable](mapFunc func(T) M, a []T) (n map[M]bool) { +func SliceMapSetFunc[T any, M comparable](mapFunc func(T) M, slice []T) (n map[M]bool) { n = make(map[M]bool, 0) - for _, e := range a { + for _, e := range slice { n[mapFunc(e)] = true } return n } +// SliceMapFunc extracts key and value for map from slice using function +// `[]Any -> map[comparable K]V` +func SliceMapFunc[T any, K comparable, V any](mapFunc func(T) (K, V), slice []T) map[K]V { + n := make(map[K]V, 0) + for _, e := range slice { + k, v := mapFunc(e) + n[k] = v + } + return n + +} + // 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 diff --git a/slice_test.go b/slice_test.go index 3c6e6db..c842655 100644 --- a/slice_test.go +++ b/slice_test.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/stretchr/testify/assert" "strconv" + "strings" "testing" ) @@ -105,7 +106,17 @@ func TestSliceMapSetFunc(t *testing.T) { assert.Equal(t, sliceMap["t3"], true) assert.Equal(t, sliceMap["t4"], false) assert.Len(t, sliceMap, 3) +} +func TestSliceMapFunc(t *testing.T) { + sliceMap := SliceMapFunc( + func(s string) (string, string) { + v := strings.Split(s, ":") + return v[0], v[1] + }, + []string{"a:b", "c:d"}, + ) + assert.Equal(t, map[string]string{"a": "b", "c": "d"}, sliceMap) } func TestSliceDiff(t *testing.T) {