From 0ac60831528378d4345f271b5a34d3bd787bef7a Mon Sep 17 00:00:00 2001 From: Aurumzhoom Lee Date: Sun, 19 May 2024 02:36:16 +0800 Subject: [PATCH 1/2] feat(map): add GetOrSet for get value of exist key or set it --- README.md | 15 +++++++++++++++ map.go | 10 ++++++++++ map_example_test.go | 10 ++++++++++ map_test.go | 27 +++++++++++++++++++++------ 4 files changed, 56 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index dd848c39..b168420f 100644 --- a/README.md +++ b/README.md @@ -958,6 +958,21 @@ value := lo.ValueOr[string, int](map[string]int{"foo": 1, "bar": 2}, "baz", 42) // 42 ``` +[[play](https://go.dev/play/p/pvoEPxdiL8m)] + +### _GetOrSet_ + +Returns the value of the given key or the fallback value if the key is not present. + +```go +value := lo.GetOrSet[string, int](map[string]int{"foo": 1, "bar": 2}, "foo", 42) +// 1 + +value := lo.GetOrSet[string, int](map[string]int{"foo": 1, "bar": 2}, "baz", 42) +// 42 +// and the original map becomes map[string]int{"foo": 1, "bar": 2, "baz": 42} +``` + [[play](https://go.dev/play/p/bAq9mHErB4V)] ### PickBy diff --git a/map.go b/map.go index 9c0ac482..0403719c 100644 --- a/map.go +++ b/map.go @@ -33,6 +33,16 @@ func ValueOr[K comparable, V any](in map[K]V, key K, fallback V) V { return fallback } +// GetOrSet returns value of the given key or set the fallback value if not present +// Play: https://go.dev/play/p/pvoEPxdiL8m +func GetOrSet[K comparable, V any](in map[K]V, key K, fallback V) V { + if v, ok := in[key]; ok { + return v + } + in[key] = fallback + return fallback +} + // PickBy returns same map type filtered by given predicate. // Play: https://go.dev/play/p/kdg8GR_QMmf func PickBy[K comparable, V any](in map[K]V, predicate func(key K, value V) bool) map[K]V { diff --git a/map_example_test.go b/map_example_test.go index aebca8fd..48308dd7 100644 --- a/map_example_test.go +++ b/map_example_test.go @@ -37,6 +37,16 @@ func ExampleValueOr() { // Output: 1 42 } +func ExampleGetOrSet() { + kv := map[string]int{"foo": 1} + + result1 := GetOrSet(kv, "foo", 1) + result2 := GetOrSet(kv, "bar", 2) + + fmt.Printf("%v %v %v", result1, result2, kv) + // Output: 1 2 map[bar:2 foo:1] +} + func ExamplePickBy() { kv := map[string]int{"foo": 1, "bar": 2, "baz": 3} diff --git a/map_test.go b/map_test.go index 419ca9fb..694ce324 100644 --- a/map_test.go +++ b/map_test.go @@ -40,6 +40,21 @@ func TestValueOr(t *testing.T) { is.Equal(r2, 1) } +func TestGetOrSet(t *testing.T) { + t.Parallel() + is := assert.New(t) + + kv := map[string]int{"foo": 1} + + r1 := GetOrSet(kv, "foo", 2) + is.Equal(r1, 1) + + r2 := GetOrSet(kv, "bar", 2) + is.Equal(r2, 2) + + is.Equal(kv, map[string]int{"foo": 1, "bar": 2}) +} + func TestPickBy(t *testing.T) { t.Parallel() is := assert.New(t) @@ -290,18 +305,18 @@ func TestMapEntries(t *testing.T) { }, map[string]any{"b": 5}) } - //// OverlappingKeys - //// because using range over map, the order is not guaranteed - //// this test is not deterministic - //{ + // // OverlappingKeys + // // because using range over map, the order is not guaranteed + // // this test is not deterministic + // { // mapEntriesTest(t, map[string]any{"foo": 1, "foo2": 2, "Foo": 2, "Foo2": "2", "bar": "2", "ccc": true}, func(k string, v any) (string, any) { // return string(k[0]), v // }, map[string]any{"F": "2", "b": "2", "c": true, "f": 2}) // mapEntriesTest(t, map[string]string{"foo": "1", "foo2": "2", "Foo": "2", "Foo2": "2", "bar": "2", "ccc": "true"}, func(k string, v string) (string, string) { // return v, k // }, map[string]string{"1": "foo", "2": "bar", "true": "ccc"}) - //} - //NormalMappers + // } + // NormalMappers { mapEntriesTest(t, map[string]string{"foo": "1", "foo2": "2", "Foo": "2", "Foo2": "2", "bar": "2", "ccc": "true"}, func(k string, v string) (string, string) { return k, k + v From 108cbb8277aadf59ab387e4e831598e26bc8ae64 Mon Sep 17 00:00:00 2001 From: Aurumzhoom Lee Date: Sun, 19 May 2024 03:04:55 +0800 Subject: [PATCH 2/2] feat(map): fix readme note --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b168420f..e4b71b62 100644 --- a/README.md +++ b/README.md @@ -962,7 +962,7 @@ value := lo.ValueOr[string, int](map[string]int{"foo": 1, "bar": 2}, "baz", 42) ### _GetOrSet_ -Returns the value of the given key or the fallback value if the key is not present. +Returns value of the given key or set the fallback value if not present ```go value := lo.GetOrSet[string, int](map[string]int{"foo": 1, "bar": 2}, "foo", 42)