feat: adding FilterSliceToMap

This commit is contained in:
Samuel Berthe
2025-01-26 23:28:22 +01:00
parent 19d8355ae8
commit 15aea5b088
4 changed files with 92 additions and 5 deletions

View File

@@ -102,7 +102,8 @@ Supported helpers for slices:
- [Repeat](#repeat)
- [RepeatBy](#repeatby)
- [KeyBy](#keyby)
- [Associate / SliceToMap](#associate-alias-slicetomap)
- [SliceToMap / Associate](#slicetomap-alias-associate)
- [FilterSliceToMap](#filterslicetomap)
- [Keyify](#keyify)
- [Drop](#drop)
- [DropRight](#dropright)
@@ -299,6 +300,9 @@ Concurrency helpers:
- [Debounce](#debounce)
- [DebounceBy](#debounceby)
- [Throttle](#throttle)
- [ThrottleWithCount](#throttle)
- [ThrottleBy](#throttle)
- [ThrottleByWithCount](#throttle)
- [Synchronize](#synchronize)
- [Async](#async)
- [Transaction](#transaction)
@@ -756,7 +760,7 @@ result := lo.KeyBy(characters, func(char Character) string {
[[play](https://go.dev/play/p/mdaClUAT-zZ)]
### Associate (alias: SliceToMap)
### SliceToMap (alias: Associate)
Returns a map containing key-value pairs provided by transform function applied to elements of the given slice.
If any of two pairs would have the same key the last one gets added to the map.
@@ -766,7 +770,7 @@ The order of keys in returned map is not specified and is not guaranteed to be t
```go
in := []*foo{{baz: "apple", bar: 1}, {baz: "banana", bar: 2}}
aMap := lo.Associate(in, func (f *foo) (string, int) {
aMap := lo.SliceToMap(in, func (f *foo) (string, int) {
return f.baz, f.bar
})
// map[string][int]{ "apple":1, "banana":2 }
@@ -774,6 +778,26 @@ aMap := lo.Associate(in, func (f *foo) (string, int) {
[[play](https://go.dev/play/p/WHa2CfMO3Lr)]
### FilterSliceToMap
Returns a map containing key-value pairs provided by transform function applied to elements of the given slice.
If any of two pairs would have the same key the last one gets added to the map.
The order of keys in returned map is not specified and is not guaranteed to be the same from the original array.
The third return value of the transform function is a boolean that indicates whether the key-value pair should be included in the map.
```go
list := []string{"a", "aa", "aaa"}
result := lo.FilterSliceToMap(list, func(str string) (string, int, bool) {
return str, len(str), len(str) > 1
})
// map[string][int]{"aa":2 "aaa":3}
```
### Keyify
Returns a map with each unique element of the slice as a key.

View File

@@ -387,6 +387,23 @@ func SliceToMap[T any, K comparable, V any](collection []T, transform func(item
return Associate(collection, transform)
}
// FilterSliceToMap returns a map containing key-value pairs provided by transform function applied to elements of the given slice.
// If any of two pairs would have the same key the last one gets added to the map.
// The order of keys in returned map is not specified and is not guaranteed to be the same from the original array.
// The third return value of the transform function is a boolean that indicates whether the key-value pair should be included in the map.
func FilterSliceToMap[T any, K comparable, V any](collection []T, transform func(item T) (K, V, bool)) map[K]V {
result := make(map[K]V, len(collection))
for i := range collection {
k, v, ok := transform(collection[i])
if ok {
result[k] = v
}
}
return result
}
// Keyify returns a map with each unique element of the slice as a key.
func Keyify[T comparable, Slice ~[]T](collection Slice) map[T]struct{} {
result := make(map[T]struct{}, len(collection))

View File

@@ -276,10 +276,10 @@ func ExampleKeyBy() {
// Output: map[1:a 2:aa 3:aaa]
}
func ExampleAssociate() {
func ExampleSliceToMap() {
list := []string{"a", "aa", "aaa"}
result := Associate(list, func(str string) (string, int) {
result := SliceToMap(list, func(str string) (string, int) {
return str, len(str)
})
@@ -287,6 +287,17 @@ func ExampleAssociate() {
// Output: map[a:1 aa:2 aaa:3]
}
func ExampleFilterSliceToMap() {
list := []string{"a", "aa", "aaa"}
result := FilterSliceToMap(list, func(str string) (string, int, bool) {
return str, len(str), len(str) > 1
})
fmt.Printf("%v", result)
// Output: map[aa:2 aaa:3]
}
func ExampleKeyify() {
list := []string{"a", "a", "b", "b", "d"}

View File

@@ -531,6 +531,41 @@ func TestSliceToMap(t *testing.T) {
}
}
func TestFilterSliceToMap(t *testing.T) {
t.Parallel()
type foo struct {
baz string
bar int
}
transform := func(f *foo) (string, int, bool) {
return f.baz, f.bar, f.bar > 1
}
testCases := []struct {
in []*foo
expect map[string]int
}{
{
in: []*foo{{baz: "apple", bar: 1}},
expect: map[string]int{},
},
{
in: []*foo{{baz: "apple", bar: 1}, {baz: "banana", bar: 2}},
expect: map[string]int{"banana": 2},
},
{
in: []*foo{{baz: "apple", bar: 1}, {baz: "apple", bar: 2}},
expect: map[string]int{"apple": 2},
},
}
for i, testCase := range testCases {
t.Run(fmt.Sprintf("test_%d", i), func(t *testing.T) {
is := assert.New(t)
is.Equal(FilterSliceToMap(testCase.in, transform), testCase.expect)
})
}
}
func TestKeyify(t *testing.T) {
t.Parallel()
is := assert.New(t)