Skip to content

Commit

Permalink
Merge pull request #14 from votdev/issue_4282_map_slice
Browse files Browse the repository at this point in the history
Add several map and slice functions
  • Loading branch information
FrankYang0529 authored May 22, 2024
2 parents eb8883e + 378ddb1 commit ed59246
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 0 deletions.
34 changes: 34 additions & 0 deletions map.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package gocommon

// MapFilterFunc iterates over elements of map, returning a map of all elements
// the function f returns truthy for. The function f is invoked with three
// arguments: (value, key).
func MapFilterFunc[M ~map[K]V, K comparable, V any](m M, f func(V, K) bool) map[K]V {
r := make(map[K]V, len(m))
for k, v := range m {
if f(v, k) {
r[k] = v
}
}
return r
}

// MapKeys returns the keys of the map m. The keys will be in an indeterminate
// order.
func MapKeys[M ~map[K]V, K comparable, V any](m M) []K {
keys := make([]K, 0, len(m))
for k := range m {
keys = append(keys, k)
}
return keys
}

// MapValues returns the values of the map m. The values will be in an
// indeterminate order.
func MapValues[M ~map[K]V, K comparable, V any](m M) []V {
values := make([]V, 0, len(m))
for _, v := range m {
values = append(values, v)
}
return values
}
41 changes: 41 additions & 0 deletions map_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package gocommon

import (
"testing"

"github.com/stretchr/testify/assert"
)

func Test_MapFilterFunc_1(t *testing.T) {
result := MapFilterFunc(map[int]bool{1: true, 2: false, 3: true}, func(v bool, _ int) bool {
return v == true
})
assert.Equal(t, map[int]bool{1: true, 3: true}, result)
}

func Test_MapFilterFunc_2(t *testing.T) {
result := MapFilterFunc(map[string]int{"a": 1, "b": 2, "c": 3, "d": 4}, func(v int, _ string) bool {
return v <= 3
})
assert.Equal(t, map[string]int{"a": 1, "b": 2, "c": 3}, result)
}

func Test_MapKeys_1(t *testing.T) {
result := MapKeys(map[string]string{"a": "1", "b": "2"})
assert.ElementsMatch(t, []string{"a", "b"}, result)
}

func Test_MapKeys_2(t *testing.T) {
result := MapKeys(map[int]bool{1: true, 2: false})
assert.ElementsMatch(t, []int{1, 2}, result)
}

func Test_MapValues_1(t *testing.T) {
result := MapValues(map[string]string{"a": "1", "b": "2"})
assert.ElementsMatch(t, []string{"1", "2"}, result)
}

func Test_MapValues_2(t *testing.T) {
result := MapValues(map[int]bool{1: true, 2: false})
assert.ElementsMatch(t, []bool{true, false}, result)
}
11 changes: 11 additions & 0 deletions slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,14 @@ func SliceDedupe[T comparable](x []T) []T {
}
return result
}

// SliceMapFunc creates a new slice of values by running each element in the
// slice through function f. The function f is invoked with two arguments:
// (value, index).
func SliceMapFunc[S ~[]E, E any](s S, f func(E, int) E) S {
r := make(S, len(s))
for i, v := range s {
r[i] = f(v, i)
}
return r
}
13 changes: 13 additions & 0 deletions slice_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package gocommon

import (
"strings"
"testing"

"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -77,3 +78,15 @@ func (s *SliceFuncs) TestSliceDedupeString() {
require.Equal(s.T(), []string{"apple", "book", "clock", "duck", "escape", "field"}, SliceDedupe(b), "SliceDedupe should return the same slice with {apple, book, clock, duck, escape, field}")
require.Equal(s.T(), []string{"foo", "bar", "roll", "desk"}, SliceDedupe(c), "SliceDedupe should return the same slice with {foo, bar, roll, desk}")
}

func (s *SliceFuncs) TestSliceMapFunc() {
a := []int{1, 2, 3}
b := []string{"a", " b", " c "}

require.Equal(s.T(), []int{2, 4, 6}, SliceMapFunc(a, func(v int, _ int) int {
return v * 2
}), "SliceMapFunc should return {2, 4, 6}")
require.Equal(s.T(), []string{"a", "b", "c"}, SliceMapFunc(b, func(v string, _ int) string {
return strings.TrimSpace(v)
}), "SliceMapFunc should return {\"a\", \"b\", \"c\"}")
}

0 comments on commit ed59246

Please sign in to comment.