mirror of
https://github.com/samber/lo.git
synced 2025-09-26 20:11:13 +08:00
feat: adding FilterSliceToMap
This commit is contained in:
30
README.md
30
README.md
@@ -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.
|
||||
|
17
slice.go
17
slice.go
@@ -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))
|
||||
|
@@ -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"}
|
||||
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user