feat: adding FilterValues and fix FilterKeys signature

This commit is contained in:
Samuel Berthe
2025-08-24 12:41:09 +02:00
parent 7ccf4aadc4
commit f197601a93
5 changed files with 91 additions and 6 deletions

View File

@@ -147,6 +147,8 @@ Supported helpers for maps:
- [MapEntries](#mapentries)
- [MapToSlice](#maptoslice)
- [FilterMapToSlice](#FilterMapToSlice)
- [FilterKeys](#FilterKeys)
- [FilterValues](#FilterValues)
Supported math helpers:
@@ -1503,6 +1505,32 @@ result := lo.FilterMapToSlice(kv, func(k int, v int64) (string, bool) {
// []{"2_2", "4_4"}
```
### FilterKeys
Transforms a map into a slice based on predicate returns truthy for specific elements. It is a mix of `lo.Filter()` and `lo.Keys()`.
```go
kv := map[int]string{1: "foo", 2: "bar", 3: "baz"}
result := FilterKeys(kv, func(k int, v string) bool {
return v == "foo"
})
// [1]
```
### FilterValues
Transforms a map into a slice based on predicate returns truthy for specific elements. It is a mix of `lo.Filter()` and `lo.Values()`.
```go
kv := map[int]string{1: "foo", 2: "bar", 3: "baz"}
result := FilterValues(kv, func(k int, v string) bool {
return v == "foo"
})
// ["foo"]
```
### Range / RangeFrom / RangeWithSteps
Creates an array of numbers (positive and/or negative) progressing from start up to, but not including end.

View File

@@ -224,13 +224,15 @@ func TestUnion(t *testing.T) {
result1 := Union([]int{0, 1, 2, 3, 4, 5}, []int{0, 2, 10})
result2 := Union([]int{0, 1, 2, 3, 4, 5}, []int{6, 7})
result3 := Union([]int{0, 1, 2, 3, 4, 5}, []int{})
result4 := Union([]int{0, 1, 2}, []int{0, 1, 2})
result5 := Union([]int{}, []int{})
result4 := Union([]int{0, 1, 2}, []int{0, 1, 2, 3, 3})
result5 := Union([]int{0, 1, 2}, []int{0, 1, 2})
result6 := Union([]int{}, []int{})
is.Equal(result1, []int{0, 1, 2, 3, 4, 5, 10})
is.Equal(result2, []int{0, 1, 2, 3, 4, 5, 6, 7})
is.Equal(result3, []int{0, 1, 2, 3, 4, 5})
is.Equal(result4, []int{0, 1, 2})
is.Equal(result5, []int{})
is.Equal(result4, []int{0, 1, 2, 3})
is.Equal(result5, []int{0, 1, 2})
is.Equal(result6, []int{})
result11 := Union([]int{0, 1, 2, 3, 4, 5}, []int{0, 2, 10}, []int{0, 1, 11})
result12 := Union([]int{0, 1, 2, 3, 4, 5}, []int{6, 7}, []int{8, 9})

18
map.go
View File

@@ -344,8 +344,24 @@ func FilterMapToSlice[K comparable, V any, R any](in map[K]V, iteratee func(key
}
// FilterKeys transforms a map into a slice based on predicate returns truthy for specific elements.
// It is a mix of lo.Filter() and lo.Keys().
// Play: https://go.dev/play/p/OFlKXlPrBAe
func FilterKeys[K comparable, V any](in map[K]V, predicate func(key K, value V) bool) []V {
func FilterKeys[K comparable, V any](in map[K]V, predicate func(key K, value V) bool) []K {
result := make([]K, 0)
for k := range in {
if predicate(k, in[k]) {
result = append(result, k)
}
}
return result
}
// FilterValues transforms a map into a slice based on predicate returns truthy for specific elements.
// It is a mix of lo.Filter() and lo.Values().
// Play: https://go.dev/play/p/YVD5r_h-LX-
func FilterValues[K comparable, V any](in map[K]V, predicate func(key K, value V) bool) []V {
result := make([]V, 0)
for k := range in {

View File

@@ -244,3 +244,25 @@ func ExampleFilterMapToSlice() {
fmt.Printf("%v", result)
// Output: [2_2 4_4]
}
func ExampleFilterKeys() {
kv := map[int]string{1: "foo", 2: "bar", 3: "baz"}
result := FilterKeys(kv, func(k int, v string) bool {
return v == "foo"
})
fmt.Printf("%v", result)
// Output: [1]
}
func ExampleFilterValues() {
kv := map[int]string{1: "foo", 2: "bar", 3: "baz"}
result := FilterValues(kv, func(k int, v string) bool {
return v == "foo"
})
fmt.Printf("%v", result)
// Output: [foo]
}

View File

@@ -537,12 +537,29 @@ func TestFilterKeys(t *testing.T) {
result1 := FilterKeys(map[int]string{1: "foo", 2: "bar", 3: "baz"}, func(k int, v string) bool {
return v == "foo"
})
is.Equal([]string{"foo"}, result1)
is.Equal([]int{1}, result1)
is.Len(result1, 1)
result2 := FilterKeys(map[string]int{"foo": 1, "bar": 2, "baz": 3}, func(k string, v int) bool {
return false
})
is.Equal([]string{}, result2)
is.Len(result2, 0)
}
func TestFilterValues(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := FilterValues(map[int]string{1: "foo", 2: "bar", 3: "baz"}, func(k int, v string) bool {
return v == "foo"
})
is.Equal([]string{"foo"}, result1)
is.Len(result1, 1)
result2 := FilterValues(map[string]int{"foo": 1, "bar": 2, "baz": 3}, func(k string, v int) bool {
return false
})
is.Equal([]int{}, result2)
is.Len(result2, 0)
}