feat(pkg): add maps-related functions
This commit is contained in:
parent
124070116f
commit
954295f524
56
maps.go
Normal file
56
maps.go
Normal file
@ -0,0 +1,56 @@
|
||||
package generics
|
||||
|
||||
// Pair represents key-value pair
|
||||
type Pair[K comparable, V any] struct {
|
||||
Key K
|
||||
Value V
|
||||
}
|
||||
|
||||
// MapPairs returns list of map's key-value pairs
|
||||
func MapPairs[K comparable, V any](src map[K]V) []Pair[K, V] {
|
||||
dst := make([]Pair[K, V], len(src))
|
||||
idx := 0
|
||||
for k, v := range src {
|
||||
dst[idx] = Pair[K, V]{
|
||||
Key: k,
|
||||
Value: v,
|
||||
}
|
||||
idx++
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// MapKeys returns list of map's keys
|
||||
func MapKeys[K comparable, V any](src map[K]V) []K {
|
||||
dst := make([]K, len(src))
|
||||
idx := 0
|
||||
for k := range src {
|
||||
dst[idx] = k
|
||||
idx++
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// MapValues returns list of map's values
|
||||
func MapValues[K comparable, V any](src map[K]V) []V {
|
||||
dst := make([]V, len(src))
|
||||
idx := 0
|
||||
for _, v := range src {
|
||||
dst[idx] = v
|
||||
idx++
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// InvertMap returns map with keys and values swapped
|
||||
func InvertMap[K, V comparable](src map[K]V) map[V]K {
|
||||
if src == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
dst := make(map[V]K, len(src))
|
||||
for k, v := range src {
|
||||
dst[v] = k
|
||||
}
|
||||
return dst
|
||||
}
|
162
maps_test.go
Normal file
162
maps_test.go
Normal file
@ -0,0 +1,162 @@
|
||||
package generics
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestMapPairs(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
src map[string]int
|
||||
dst []Pair[string, int]
|
||||
}{
|
||||
"nil map": {
|
||||
src: nil,
|
||||
dst: []Pair[string, int]{},
|
||||
},
|
||||
"empty map": {
|
||||
src: map[string]int{},
|
||||
dst: []Pair[string, int]{},
|
||||
},
|
||||
"filled map": {
|
||||
src: map[string]int{
|
||||
"foo": 1,
|
||||
"bar": 2,
|
||||
"baz": 3,
|
||||
},
|
||||
dst: []Pair[string, int]{
|
||||
{
|
||||
Key: "foo",
|
||||
Value: 1,
|
||||
},
|
||||
{
|
||||
Key: "bar",
|
||||
Value: 2,
|
||||
},
|
||||
{
|
||||
Key: "baz",
|
||||
Value: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range tests {
|
||||
name, tc := name, tc
|
||||
t.Run(name, func(t *testing.T) {
|
||||
dst := MapPairs(tc.src)
|
||||
require.ElementsMatch(t, tc.dst, dst)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMapKeys(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
src map[string]int
|
||||
dst []string
|
||||
}{
|
||||
"nil map": {
|
||||
src: nil,
|
||||
dst: []string{},
|
||||
},
|
||||
"empty map": {
|
||||
src: map[string]int{},
|
||||
dst: []string{},
|
||||
},
|
||||
"filled map": {
|
||||
src: map[string]int{
|
||||
"foo": 1,
|
||||
"bar": 2,
|
||||
"baz": 3,
|
||||
},
|
||||
dst: []string{
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range tests {
|
||||
name, tc := name, tc
|
||||
t.Run(name, func(t *testing.T) {
|
||||
dst := MapKeys(tc.src)
|
||||
require.ElementsMatch(t, tc.dst, dst)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMapValues(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
src map[string]int
|
||||
dst []int
|
||||
}{
|
||||
"nil map": {
|
||||
src: nil,
|
||||
dst: []int{},
|
||||
},
|
||||
"empty map": {
|
||||
src: map[string]int{},
|
||||
dst: []int{},
|
||||
},
|
||||
"filled map": {
|
||||
src: map[string]int{
|
||||
"foo": 1,
|
||||
"bar": 2,
|
||||
"baz": 3,
|
||||
},
|
||||
dst: []int{1, 2, 3},
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range tests {
|
||||
name, tc := name, tc
|
||||
t.Run(name, func(t *testing.T) {
|
||||
dst := MapValues(tc.src)
|
||||
require.ElementsMatch(t, tc.dst, dst)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvertMap(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
src map[string]int
|
||||
dst map[int]string
|
||||
}{
|
||||
"nil map": {
|
||||
src: nil,
|
||||
dst: nil,
|
||||
},
|
||||
"empty map": {
|
||||
src: map[string]int{},
|
||||
dst: map[int]string{},
|
||||
},
|
||||
"filled map": {
|
||||
src: map[string]int{
|
||||
"foo": 1,
|
||||
"bar": 2,
|
||||
"baz": 3,
|
||||
},
|
||||
dst: map[int]string{
|
||||
1: "foo",
|
||||
2: "bar",
|
||||
3: "baz",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range tests {
|
||||
name, tc := name, tc
|
||||
t.Run(name, func(t *testing.T) {
|
||||
dst := InvertMap(tc.src)
|
||||
|
||||
if tc.dst == nil {
|
||||
require.Nil(t, dst)
|
||||
return
|
||||
}
|
||||
require.NotNil(t, dst)
|
||||
require.EqualValues(t, tc.dst, dst)
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user