From e06396b1f82edeb2a7c1cdde5ccada220521f1db Mon Sep 17 00:00:00 2001 From: shivam bhalla Date: Fri, 19 Jul 2024 22:23:41 +0530 Subject: [PATCH 01/22] added Keys: accept multiple maps (vaargs) --- README.md | 3 +++ map.go | 12 ++++++------ map_example_test.go | 8 ++++---- map_test.go | 8 ++++++-- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index cd836ac0..6c1f1328 100644 --- a/README.md +++ b/README.md @@ -1043,6 +1043,9 @@ Creates an array of the map keys. ```go keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}) // []string{"foo", "bar"} + +keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3}) +// []string{"foo", "bar", "baz"} ``` [[play](https://go.dev/play/p/Uu11fHASqrU)] diff --git a/map.go b/map.go index 59343bc1..11df6257 100644 --- a/map.go +++ b/map.go @@ -2,13 +2,13 @@ package lo // Keys creates an array of the map keys. // Play: https://go.dev/play/p/Uu11fHASqrU -func Keys[K comparable, V any](in map[K]V) []K { - result := make([]K, 0, len(in)) - - for k := range in { - result = append(result, k) +func Keys[K comparable, V any](in ...map[K]V) []K { + result := make([]K, 0) + for i := range in { + for k := range in[i] { + result = append(result, k) + } } - return result } diff --git a/map_example_test.go b/map_example_test.go index aebca8fd..314690ae 100644 --- a/map_example_test.go +++ b/map_example_test.go @@ -9,12 +9,12 @@ import ( func ExampleKeys() { kv := map[string]int{"foo": 1, "bar": 2} + kv2 := map[string]int{"baz": 3} - result := Keys(kv) - - sort.StringSlice(result).Sort() + result := Keys(kv, kv2) fmt.Printf("%v", result) - // Output: [bar foo] + // Output: [foo bar baz] + } func ExampleValues() { diff --git a/map_test.go b/map_test.go index c683cbe1..e164e45e 100644 --- a/map_test.go +++ b/map_test.go @@ -14,9 +14,13 @@ func TestKeys(t *testing.T) { is := assert.New(t) r1 := Keys(map[string]int{"foo": 1, "bar": 2}) - sort.Strings(r1) + is.Equal(r1, []string{"foo", "bar"}) - is.Equal(r1, []string{"bar", "foo"}) + r2 := Keys(map[string]int{}) + is.Empty(r2) + + r3 := Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3}) + is.Equal(r3, []string{"foo", "bar", "baz"}) } func TestHasKey(t *testing.T) { From 9e13c9b612d1209fd287ebd4159e690e4745858b Mon Sep 17 00:00:00 2001 From: shivam bhalla Date: Sat, 20 Jul 2024 11:44:05 +0530 Subject: [PATCH 02/22] added test:review comment fix --- map_test.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/map_test.go b/map_test.go index e164e45e..965b6a2b 100644 --- a/map_test.go +++ b/map_test.go @@ -21,6 +21,12 @@ func TestKeys(t *testing.T) { r3 := Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3}) is.Equal(r3, []string{"foo", "bar", "baz"}) + + r4 := Keys[string, int]() + is.Equal(r4, []string{}) + + r5 := Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 3}) + is.Equal(r5, []string{"foo", "bar", "bar"}) } func TestHasKey(t *testing.T) { From 4ef8b772b0b02cbc02b3a144ea34708725288d64 Mon Sep 17 00:00:00 2001 From: shivam bhalla Date: Sat, 20 Jul 2024 11:52:32 +0530 Subject: [PATCH 03/22] added sort before asserting :review comment fix --- map_test.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/map_test.go b/map_test.go index 965b6a2b..10e09e43 100644 --- a/map_test.go +++ b/map_test.go @@ -14,19 +14,22 @@ func TestKeys(t *testing.T) { is := assert.New(t) r1 := Keys(map[string]int{"foo": 1, "bar": 2}) - is.Equal(r1, []string{"foo", "bar"}) + sort.Strings(r1) + is.Equal(r1, []string{"bar", "foo"}) r2 := Keys(map[string]int{}) is.Empty(r2) r3 := Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3}) - is.Equal(r3, []string{"foo", "bar", "baz"}) + sort.Strings(r3) + is.Equal(r3, []string{"bar", "baz", "foo"}) - r4 := Keys[string, int]() - is.Equal(r4, []string{}) + r4 := Keys[int, int]() + is.Equal(r4, []int{}) r5 := Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 3}) - is.Equal(r5, []string{"foo", "bar", "bar"}) + sort.Strings(r5) + is.Equal(r5, []string{"bar", "bar", "foo"}) } func TestHasKey(t *testing.T) { From cadc6eaca6d593220f2ba3d1d43b83b891ebd187 Mon Sep 17 00:00:00 2001 From: shivam bhalla Date: Sat, 20 Jul 2024 11:53:59 +0530 Subject: [PATCH 04/22] added sort before asserting :review comment fix --- map_example_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/map_example_test.go b/map_example_test.go index 314690ae..69328e52 100644 --- a/map_example_test.go +++ b/map_example_test.go @@ -12,8 +12,9 @@ func ExampleKeys() { kv2 := map[string]int{"baz": 3} result := Keys(kv, kv2) + sort.StringSlice(result).Sort() fmt.Printf("%v", result) - // Output: [foo bar baz] + // Output: [bar baz foo] } From c6624701e8e819bfb4a936f0829c3c4b72c49d3e Mon Sep 17 00:00:00 2001 From: shivam bhalla Date: Sat, 20 Jul 2024 12:11:27 +0530 Subject: [PATCH 05/22] output unique keys --- README.md | 6 +++++- map.go | 8 +++++++- map_test.go | 6 +++--- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 6c1f1328..011d4502 100644 --- a/README.md +++ b/README.md @@ -1038,7 +1038,8 @@ result = lo.Splice([]string{"a", "b"}, 42, "1", "2") ### Keys -Creates an array of the map keys. +Creates an array of the unique map keys. +(Note: The order of the keys is not guaranteed to be the same as the order returned by the map, so can sort them if needed.) ```go keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}) @@ -1046,6 +1047,9 @@ keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}) keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3}) // []string{"foo", "bar", "baz"} + +keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 3}) +// []string{"foo", "bar"} ``` [[play](https://go.dev/play/p/Uu11fHASqrU)] diff --git a/map.go b/map.go index 11df6257..e9681949 100644 --- a/map.go +++ b/map.go @@ -3,12 +3,18 @@ package lo // Keys creates an array of the map keys. // Play: https://go.dev/play/p/Uu11fHASqrU func Keys[K comparable, V any](in ...map[K]V) []K { + seen := make(map[K]bool) result := make([]K, 0) + for i := range in { for k := range in[i] { - result = append(result, k) + if _, exists := seen[k]; !exists { + seen[k] = true + result = append(result, k) + } } } + return result } diff --git a/map_test.go b/map_test.go index 10e09e43..7808c8ae 100644 --- a/map_test.go +++ b/map_test.go @@ -24,12 +24,12 @@ func TestKeys(t *testing.T) { sort.Strings(r3) is.Equal(r3, []string{"bar", "baz", "foo"}) - r4 := Keys[int, int]() - is.Equal(r4, []int{}) + r4 := Keys[string, int]() + is.Equal(r4, []string{}) r5 := Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 3}) sort.Strings(r5) - is.Equal(r5, []string{"bar", "bar", "foo"}) + is.Equal(r5, []string{"bar", "foo"}) } func TestHasKey(t *testing.T) { From f966312baa9e8f304baddc2248801aae7d669fd0 Mon Sep 17 00:00:00 2001 From: shivam bhalla Date: Tue, 23 Jul 2024 08:39:41 +0530 Subject: [PATCH 06/22] added map functions" --- map.go | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/map.go b/map.go index e9681949..bdc14d1a 100644 --- a/map.go +++ b/map.go @@ -3,6 +3,20 @@ package lo // Keys creates an array of the map keys. // Play: https://go.dev/play/p/Uu11fHASqrU func Keys[K comparable, V any](in ...map[K]V) []K { + result := make([]K, 0) + + for i := range in { + for k := range in[i] { + result = append(result, k) + } + } + + return result +} + +// UniqKeys creates an array of unique keys in the map. +// Play: +func UniqKeys[K comparable, V any](in ...map[K]V) []K { seen := make(map[K]bool) result := make([]K, 0) @@ -27,11 +41,31 @@ func HasKey[K comparable, V any](in map[K]V, key K) bool { // Values creates an array of the map values. // Play: https://go.dev/play/p/nnRTQkzQfF6 -func Values[K comparable, V any](in map[K]V) []V { +func Values[K comparable, V any](in ...map[K]V) []V { result := make([]V, 0, len(in)) - for k := range in { - result = append(result, in[k]) + for i := range in { + for k := range in[i] { + result = append(result, in[i][k]) + } + } + + return result +} + +// UniqValues creates an array of unique values in the map. +// Play: +func UniqValues[K comparable, V comparable](in ...map[K]V) []V { + seen := make(map[V]bool) + result := make([]V, 0) + + for i := range in { + for k := range in[i] { + if _, exists := seen[in[i][k]]; !exists { + seen[in[i][k]] = true + result = append(result, in[i][k]) + } + } } return result From 18b6dc9cc0366771cb25191e4434ccd427f555af Mon Sep 17 00:00:00 2001 From: shivam bhalla Date: Tue, 23 Jul 2024 09:53:05 +0530 Subject: [PATCH 07/22] added map_test.go and README.md --- README.md | 46 ++++++++++++++++++++++++++++++++++++-- map_test.go | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 011d4502..ccf6e181 100644 --- a/README.md +++ b/README.md @@ -125,9 +125,11 @@ Supported helpers for slices: Supported helpers for maps: - [Keys](#keys) +- [UniqKeys](#keys) - [HasKey](#HasKey) - [ValueOr](#valueor) - [Values](#values) +- [UniqValues](#keys) - [PickBy](#pickby) - [PickByKeys](#pickbykeys) - [PickByValues](#pickbyvalues) @@ -1038,7 +1040,7 @@ result = lo.Splice([]string{"a", "b"}, 42, "1", "2") ### Keys -Creates an array of the unique map keys. +Creates an array of the map keys. (Note: The order of the keys is not guaranteed to be the same as the order returned by the map, so can sort them if needed.) ```go @@ -1049,11 +1051,26 @@ keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3}) // []string{"foo", "bar", "baz"} keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 3}) -// []string{"foo", "bar"} +// []string{"foo", "bar", "bar"} ``` [[play](https://go.dev/play/p/Uu11fHASqrU)] +### UniqKeys + +Creates an array of the unique map keys. +(Note: The order of the keys is not guaranteed to be the same as the order returned by the map, so can sort them if needed.) + +```go +keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3}) +// []string{"foo", "bar", "baz"} + +keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 3}) +// []string{"foo", "bar"} +``` + +[[play]()] + ### HasKey Returns whether the given key exists. @@ -1071,14 +1088,39 @@ exists := lo.HasKey(map[string]int{"foo": 1, "bar": 2}, "baz") ### Values Creates an array of the map values. +(Note: The order of the values is not guaranteed to be the same as the order returned by the map, so can sort them if needed.) ```go values := lo.Values(map[string]int{"foo": 1, "bar": 2}) // []int{1, 2} + +values := lo.Values(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3}) +// []int{1, 2, 3} + +values := lo.Values(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 2}) +// []int{1, 2, 2} ``` [[play](https://go.dev/play/p/nnRTQkzQfF6)] +### UniqValues + +Creates an array of the unique map values. +(Note: The order of the values is not guaranteed to be the same as the order returned by the map, so can sort them if needed.) + +```go +values := lo.Values(map[string]int{"foo": 1, "bar": 2}) +// []int{1, 2} + +values := lo.Values(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3}) +// []int{1, 2, 3} + +values := lo.Values(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 2}) +// []int{1, 2} +``` + +[[play]()] + ### ValueOr Returns the value of the given key or the fallback value if the key is not present. diff --git a/map_test.go b/map_test.go index 7808c8ae..b6f94ccd 100644 --- a/map_test.go +++ b/map_test.go @@ -29,6 +29,29 @@ func TestKeys(t *testing.T) { r5 := Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 3}) sort.Strings(r5) + is.Equal(r5, []string{"bar", "bar", "foo"}) +} + +func TestUniqKeys(t *testing.T) { + t.Parallel() + is := assert.New(t) + + r1 := UniqKeys(map[string]int{"foo": 1, "bar": 2}) + sort.Strings(r1) + is.Equal(r1, []string{"bar", "foo"}) + + r2 := UniqKeys(map[string]int{}) + is.Empty(r2) + + r3 := UniqKeys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3}) + sort.Strings(r3) + is.Equal(r3, []string{"bar", "baz", "foo"}) + + r4 := UniqKeys[string, int]() + is.Equal(r4, []string{}) + + r5 := UniqKeys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"foo": 1, "bar": 3}) + sort.Strings(r5) is.Equal(r5, []string{"bar", "foo"}) } @@ -49,8 +72,48 @@ func TestValues(t *testing.T) { r1 := Values(map[string]int{"foo": 1, "bar": 2}) sort.Ints(r1) + is.Equal(r1, []int{1, 2}) + r2 := Values(map[string]int{}) + is.Empty(r2) + + r3 := Values(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3}) + sort.Ints(r1) + is.Equal(r3, []int{1, 2, 3}) + + r4 := Values[string, int]() + is.Equal(r4, []int{}) + + r5 := Values(map[string]int{"foo": 1, "bar": 2}, map[string]int{"foo": 1, "bar": 3}) + sort.Ints(r5) + is.Equal(r5, []int{1, 1, 2, 3}) +} + +func TestUniqValues(t *testing.T) { + t.Parallel() + is := assert.New(t) + + r1 := UniqValues(map[string]int{"foo": 1, "bar": 2}) + sort.Ints(r1) is.Equal(r1, []int{1, 2}) + + r2 := UniqValues(map[string]int{}) + is.Empty(r2) + + r3 := UniqValues(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3}) + sort.Ints(r1) + is.Equal(r3, []int{1, 2, 3}) + + r4 := UniqValues[string, int]() + is.Equal(r4, []int{}) + + r5 := UniqValues(map[string]int{"foo": 1, "bar": 2}, map[string]int{"foo": 1, "bar": 3}) + sort.Ints(r5) + is.Equal(r5, []int{1, 2, 3}) + + r6 := UniqValues(map[string]int{"foo": 1, "bar": 1}, map[string]int{"foo": 1, "bar": 3}) + sort.Ints(r6) + is.Equal(r6, []int{1, 3}) } func TestValueOr(t *testing.T) { From 005192acc57cdec90a67fc9ebc29dd5ced1e4117 Mon Sep 17 00:00:00 2001 From: shivam bhalla Date: Tue, 23 Jul 2024 09:59:02 +0530 Subject: [PATCH 08/22] added anchor in README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ccf6e181..0486ad3f 100644 --- a/README.md +++ b/README.md @@ -125,11 +125,11 @@ Supported helpers for slices: Supported helpers for maps: - [Keys](#keys) -- [UniqKeys](#keys) +- [UniqKeys](#uniqkeys) - [HasKey](#HasKey) - [ValueOr](#valueor) - [Values](#values) -- [UniqValues](#keys) +- [UniqValues](#uniqvalues) - [PickBy](#pickby) - [PickByKeys](#pickbykeys) - [PickByValues](#pickbyvalues) From f0b33282a5f59272f69c6af599f5198c392fa277 Mon Sep 17 00:00:00 2001 From: shivam bhalla Date: Tue, 23 Jul 2024 10:01:14 +0530 Subject: [PATCH 09/22] added breakline in README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0486ad3f..5dd0998d 100644 --- a/README.md +++ b/README.md @@ -1040,7 +1040,7 @@ result = lo.Splice([]string{"a", "b"}, 42, "1", "2") ### Keys -Creates an array of the map keys. +Creates an array of the map keys.
(Note: The order of the keys is not guaranteed to be the same as the order returned by the map, so can sort them if needed.) ```go @@ -1058,7 +1058,7 @@ keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 3}) ### UniqKeys -Creates an array of the unique map keys. +Creates an array of the unique map keys.
(Note: The order of the keys is not guaranteed to be the same as the order returned by the map, so can sort them if needed.) ```go From 385272987f5538aaba7bd5e2767a22cc7d64a217 Mon Sep 17 00:00:00 2001 From: shivam bhalla Date: Tue, 23 Jul 2024 10:03:40 +0530 Subject: [PATCH 10/22] fix README.md --- README.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5dd0998d..b681f572 100644 --- a/README.md +++ b/README.md @@ -125,11 +125,11 @@ Supported helpers for slices: Supported helpers for maps: - [Keys](#keys) -- [UniqKeys](#uniqkeys) +- [UniqKeys](#UniqKeys) - [HasKey](#HasKey) - [ValueOr](#valueor) - [Values](#values) -- [UniqValues](#uniqvalues) +- [UniqValues](#UniqValues) - [PickBy](#pickby) - [PickByKeys](#pickbykeys) - [PickByValues](#pickbyvalues) @@ -1040,8 +1040,10 @@ result = lo.Splice([]string{"a", "b"}, 42, "1", "2") ### Keys -Creates an array of the map keys.
-(Note: The order of the keys is not guaranteed to be the same as the order returned by the map, so can sort them if needed.) +Creates an array of the map keys. +
+(Note: The order of the keys is not guaranteed to be the same as the order returned by the map, +so can sort them if needed.) ```go keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}) @@ -1058,7 +1060,8 @@ keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 3}) ### UniqKeys -Creates an array of the unique map keys.
+Creates an array of the unique map keys. +
(Note: The order of the keys is not guaranteed to be the same as the order returned by the map, so can sort them if needed.) ```go @@ -1088,6 +1091,7 @@ exists := lo.HasKey(map[string]int{"foo": 1, "bar": 2}, "baz") ### Values Creates an array of the map values. +
(Note: The order of the values is not guaranteed to be the same as the order returned by the map, so can sort them if needed.) ```go @@ -1106,6 +1110,7 @@ values := lo.Values(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 2} ### UniqValues Creates an array of the unique map values. +
(Note: The order of the values is not guaranteed to be the same as the order returned by the map, so can sort them if needed.) ```go From d7ab831b715e93770de72931aa2ceb4974cf842a Mon Sep 17 00:00:00 2001 From: shivam bhalla Date: Tue, 23 Jul 2024 10:07:20 +0530 Subject: [PATCH 11/22] fix README.md and added test --- README.md | 6 +++--- map_example_test.go | 25 ++++++++++++++++++++++++- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b681f572..74fa2b98 100644 --- a/README.md +++ b/README.md @@ -125,11 +125,11 @@ Supported helpers for slices: Supported helpers for maps: - [Keys](#keys) -- [UniqKeys](#UniqKeys) -- [HasKey](#HasKey) +- [UniqKeys](#uniqKeys) +- [HasKey](#hasKey) - [ValueOr](#valueor) - [Values](#values) -- [UniqValues](#UniqValues) +- [UniqValues](#uniqValues) - [PickBy](#pickby) - [PickByKeys](#pickbykeys) - [PickByValues](#pickbyvalues) diff --git a/map_example_test.go b/map_example_test.go index 69328e52..af43de72 100644 --- a/map_example_test.go +++ b/map_example_test.go @@ -18,10 +18,33 @@ func ExampleKeys() { } +func ExampleUniqKeys() { + kv := map[string]int{"foo": 1, "bar": 2} + kv2 := map[string]int{"bar": 3} + + result := UniqKeys(kv, kv2) + sort.StringSlice(result).Sort() + fmt.Printf("%v", result) + // Output: [bar foo] + +} + func ExampleValues() { kv := map[string]int{"foo": 1, "bar": 2} + kv2 := map[string]int{"baz": 3} + + result := Values(kv, kv2) + + sort.IntSlice(result).Sort() + fmt.Printf("%v", result) + // Output: [1 2 3] +} + +func ExampleUniqValues() { + kv := map[string]int{"foo": 1, "bar": 2} + kv2 := map[string]int{"baz": 2} - result := Values(kv) + result := UniqValues(kv, kv2) sort.IntSlice(result).Sort() fmt.Printf("%v", result) From f5741e70cd0d07145233df82f1676cb07224d62d Mon Sep 17 00:00:00 2001 From: shivam bhalla Date: Tue, 23 Jul 2024 12:29:22 +0530 Subject: [PATCH 12/22] fix comments --- README.md | 23 +++++++++++------------ map.go | 18 ++++++++++-------- map_example_test.go | 8 ++++---- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 74fa2b98..404d0714 100644 --- a/README.md +++ b/README.md @@ -1040,10 +1040,9 @@ result = lo.Splice([]string{"a", "b"}, 42, "1", "2") ### Keys -Creates an array of the map keys. -
-(Note: The order of the keys is not guaranteed to be the same as the order returned by the map, -so can sort them if needed.) +Creates a slice of the map keys. +> [!NOTE] +> The order of the keys is not guaranteed to be the same as the order returned by the map, so can sort them if needed. ```go keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}) @@ -1061,8 +1060,8 @@ keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 3}) ### UniqKeys Creates an array of the unique map keys. -
-(Note: The order of the keys is not guaranteed to be the same as the order returned by the map, so can sort them if needed.) +> [!NOTE] +> The order of the keys is not guaranteed to be the same as the order returned by the map, so can sort them if needed. ```go keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3}) @@ -1072,7 +1071,7 @@ keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 3}) // []string{"foo", "bar"} ``` -[[play]()] +[[play](https://go.dev/play/p/RyIE6Pb5dVS)] ### HasKey @@ -1091,8 +1090,8 @@ exists := lo.HasKey(map[string]int{"foo": 1, "bar": 2}, "baz") ### Values Creates an array of the map values. -
-(Note: The order of the values is not guaranteed to be the same as the order returned by the map, so can sort them if needed.) +> [!NOTE] +> The order of the values is not guaranteed to be the same as the order returned by the map, so can sort them if needed. ```go values := lo.Values(map[string]int{"foo": 1, "bar": 2}) @@ -1110,8 +1109,8 @@ values := lo.Values(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 2} ### UniqValues Creates an array of the unique map values. -
-(Note: The order of the values is not guaranteed to be the same as the order returned by the map, so can sort them if needed.) +> [!NOTE] +> The order of the values is not guaranteed to be the same as the order returned by the map, so can sort them if needed. ```go values := lo.Values(map[string]int{"foo": 1, "bar": 2}) @@ -1124,7 +1123,7 @@ values := lo.Values(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 2} // []int{1, 2} ``` -[[play]()] +[[play](https://go.dev/play/p/RxsJbnaJn3I)] ### ValueOr diff --git a/map.go b/map.go index bdc14d1a..15d17286 100644 --- a/map.go +++ b/map.go @@ -15,15 +15,15 @@ func Keys[K comparable, V any](in ...map[K]V) []K { } // UniqKeys creates an array of unique keys in the map. -// Play: +// Play: https://go.dev/play/p/RyIE6Pb5dVS func UniqKeys[K comparable, V any](in ...map[K]V) []K { - seen := make(map[K]bool) + seen := make(map[K]struct{}) result := make([]K, 0) for i := range in { for k := range in[i] { if _, exists := seen[k]; !exists { - seen[k] = true + seen[k] = struct{}{} result = append(result, k) } } @@ -54,18 +54,20 @@ func Values[K comparable, V any](in ...map[K]V) []V { } // UniqValues creates an array of unique values in the map. -// Play: +// Play: https://go.dev/play/p/RxsJbnaJn3I func UniqValues[K comparable, V comparable](in ...map[K]V) []V { - seen := make(map[V]bool) + seen := make(map[V]struct{}) result := make([]V, 0) for i := range in { for k := range in[i] { - if _, exists := seen[in[i][k]]; !exists { - seen[in[i][k]] = true - result = append(result, in[i][k]) + val := in[i][k] + if _, exists := seen[val]; !exists { + seen[val] = struct{}{} + result = append(result, val) } } + } return result diff --git a/map_example_test.go b/map_example_test.go index af43de72..3a9b66ab 100644 --- a/map_example_test.go +++ b/map_example_test.go @@ -12,7 +12,7 @@ func ExampleKeys() { kv2 := map[string]int{"baz": 3} result := Keys(kv, kv2) - sort.StringSlice(result).Sort() + sort.Strings(result) fmt.Printf("%v", result) // Output: [bar baz foo] @@ -23,7 +23,7 @@ func ExampleUniqKeys() { kv2 := map[string]int{"bar": 3} result := UniqKeys(kv, kv2) - sort.StringSlice(result).Sort() + sort.Strings(result) fmt.Printf("%v", result) // Output: [bar foo] @@ -35,7 +35,7 @@ func ExampleValues() { result := Values(kv, kv2) - sort.IntSlice(result).Sort() + sort.Ints(result) fmt.Printf("%v", result) // Output: [1 2 3] } @@ -46,7 +46,7 @@ func ExampleUniqValues() { result := UniqValues(kv, kv2) - sort.IntSlice(result).Sort() + sort.Ints(result) fmt.Printf("%v", result) // Output: [1 2] } From 97540409f2d2aaa47f4431ee11efe6767e082b03 Mon Sep 17 00:00:00 2001 From: shivam bhalla Date: Tue, 23 Jul 2024 12:44:29 +0530 Subject: [PATCH 13/22] fix comments --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9f29aecc..f3ad77b6 100644 --- a/README.md +++ b/README.md @@ -1042,7 +1042,7 @@ result = lo.Splice([]string{"a", "b"}, 42, "1", "2") Creates a slice of the map keys. > [!NOTE] -> The order of the keys is not guaranteed to be the same as the order returned by the map, so can sort them if needed. +> The order of the keys isn't guaranteed to be sorted, so sort the output slice if needed. ```go keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}) @@ -1061,7 +1061,7 @@ keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 3}) Creates an array of the unique map keys. > [!NOTE] -> The order of the keys is not guaranteed to be the same as the order returned by the map, so can sort them if needed. +> The order of the keys isn't guaranteed to be sorted, so sort the output slice if needed. ```go keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3}) @@ -1091,7 +1091,7 @@ exists := lo.HasKey(map[string]int{"foo": 1, "bar": 2}, "baz") Creates an array of the map values. > [!NOTE] -> The order of the values is not guaranteed to be the same as the order returned by the map, so can sort them if needed. +> The order of the values isn't guaranteed to be sorted, so sort the output slice if needed. ```go values := lo.Values(map[string]int{"foo": 1, "bar": 2}) @@ -1110,7 +1110,7 @@ values := lo.Values(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 2} Creates an array of the unique map values. > [!NOTE] -> The order of the values is not guaranteed to be the same as the order returned by the map, so can sort them if needed. +> The order of the values isn't guaranteed to be sorted, so sort the output slice if needed. ```go values := lo.Values(map[string]int{"foo": 1, "bar": 2}) From e426cdef67113a50f24a7a546945ff42067eac1b Mon Sep 17 00:00:00 2001 From: shivam bhalla Date: Tue, 23 Jul 2024 14:38:37 +0530 Subject: [PATCH 14/22] fix comments --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f3ad77b6..3173335c 100644 --- a/README.md +++ b/README.md @@ -1042,7 +1042,7 @@ result = lo.Splice([]string{"a", "b"}, 42, "1", "2") Creates a slice of the map keys. > [!NOTE] -> The order of the keys isn't guaranteed to be sorted, so sort the output slice if needed. +> The order of the keys isn't guaranteed to be sorted for performance reason, so sort the output slice if needed. ```go keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}) @@ -1061,7 +1061,7 @@ keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 3}) Creates an array of the unique map keys. > [!NOTE] -> The order of the keys isn't guaranteed to be sorted, so sort the output slice if needed. +> The order of the keys isn't guaranteed to be sorted for performance reason, so sort the output slice if needed. ```go keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3}) @@ -1091,7 +1091,7 @@ exists := lo.HasKey(map[string]int{"foo": 1, "bar": 2}, "baz") Creates an array of the map values. > [!NOTE] -> The order of the values isn't guaranteed to be sorted, so sort the output slice if needed. +> The order of the values isn't guaranteed to be sorted for performance reason, so sort the output slice if needed. ```go values := lo.Values(map[string]int{"foo": 1, "bar": 2}) @@ -1110,7 +1110,7 @@ values := lo.Values(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 2} Creates an array of the unique map values. > [!NOTE] -> The order of the values isn't guaranteed to be sorted, so sort the output slice if needed. +> The order of the values isn't guaranteed to be sorted for performance reason, so sort the output slice if needed. ```go values := lo.Values(map[string]int{"foo": 1, "bar": 2}) From 8a0ad18a0326f0638bdf21c31bceb22ccb03bbd8 Mon Sep 17 00:00:00 2001 From: shivam bhalla Date: Wed, 24 Jul 2024 10:54:52 +0530 Subject: [PATCH 15/22] fix comments --- map.go | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/map.go b/map.go index 15d17286..9f558add 100644 --- a/map.go +++ b/map.go @@ -22,10 +22,11 @@ func UniqKeys[K comparable, V any](in ...map[K]V) []K { for i := range in { for k := range in[i] { - if _, exists := seen[k]; !exists { - seen[k] = struct{}{} - result = append(result, k) + if _, exists := seen[k]; exists { + continue } + seen[k] = struct{}{} + result = append(result, k) } } @@ -62,12 +63,12 @@ func UniqValues[K comparable, V comparable](in ...map[K]V) []V { for i := range in { for k := range in[i] { val := in[i][k] - if _, exists := seen[val]; !exists { - seen[val] = struct{}{} - result = append(result, val) + if _, exists := seen[val]; exists { + continue } + seen[val] = struct{}{} + result = append(result, val) } - } return result From 7efe1b505f2e7e1b0f07616dee47701b16cde8de Mon Sep 17 00:00:00 2001 From: shivam bhalla Date: Wed, 24 Jul 2024 15:40:21 +0530 Subject: [PATCH 16/22] fix comments --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3173335c..df6294f1 100644 --- a/README.md +++ b/README.md @@ -125,11 +125,11 @@ Supported helpers for slices: Supported helpers for maps: - [Keys](#keys) -- [UniqKeys](#uniqKeys) -- [HasKey](#hasKey) +- [UniqKeys](#uniqkeys) +- [HasKey](#haskey) - [ValueOr](#valueor) - [Values](#values) -- [UniqValues](#uniqValues) +- [UniqValues](#uniqvalues) - [PickBy](#pickby) - [PickByKeys](#pickbykeys) - [PickByValues](#pickbyvalues) From 333ca37b138abd0c57da269293d303fe89688098 Mon Sep 17 00:00:00 2001 From: Samuel Berthe Date: Fri, 26 Jul 2024 08:17:46 +0200 Subject: [PATCH 17/22] Update README.md --- README.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index df6294f1..4be49885 100644 --- a/README.md +++ b/README.md @@ -1041,8 +1041,8 @@ result = lo.Splice([]string{"a", "b"}, 42, "1", "2") ### Keys Creates a slice of the map keys. -> [!NOTE] -> The order of the keys isn't guaranteed to be sorted for performance reason, so sort the output slice if needed. + +Use the UniqKeys variant to deduplicate common keys. ```go keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}) @@ -1060,8 +1060,6 @@ keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 3}) ### UniqKeys Creates an array of the unique map keys. -> [!NOTE] -> The order of the keys isn't guaranteed to be sorted for performance reason, so sort the output slice if needed. ```go keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3}) @@ -1108,9 +1106,9 @@ values := lo.Values(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 2} ### UniqValues -Creates an array of the unique map values. -> [!NOTE] -> The order of the values isn't guaranteed to be sorted for performance reason, so sort the output slice if needed. +Creates an array of unique map values. + +Use the UniqValues variant to deduplicate common values. ```go values := lo.Values(map[string]int{"foo": 1, "bar": 2}) From 368c1f76c4ece66cbd310e8279a4673088ecea1a Mon Sep 17 00:00:00 2001 From: shivam bhalla Date: Fri, 26 Jul 2024 19:47:53 +0530 Subject: [PATCH 18/22] small typo --- map_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/map_test.go b/map_test.go index b6f94ccd..1dd4aa80 100644 --- a/map_test.go +++ b/map_test.go @@ -78,7 +78,7 @@ func TestValues(t *testing.T) { is.Empty(r2) r3 := Values(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3}) - sort.Ints(r1) + sort.Ints(r3) is.Equal(r3, []int{1, 2, 3}) r4 := Values[string, int]() From e7746b769cd00cdd13b6b91db600680adbe2ac23 Mon Sep 17 00:00:00 2001 From: Samuel Berthe Date: Mon, 29 Jul 2024 05:28:23 +0200 Subject: [PATCH 19/22] Update README.md --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 68795fcb..55187a29 100644 --- a/README.md +++ b/README.md @@ -1090,8 +1090,8 @@ exists := lo.HasKey(map[string]int{"foo": 1, "bar": 2}, "baz") ### Values Creates an array of the map values. -> [!NOTE] -> The order of the values isn't guaranteed to be sorted for performance reason, so sort the output slice if needed. + +Use the UniqValues variant to deduplicate common values. ```go values := lo.Values(map[string]int{"foo": 1, "bar": 2}) @@ -1110,8 +1110,6 @@ values := lo.Values(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 2} Creates an array of unique map values. -Use the UniqValues variant to deduplicate common values. - ```go values := lo.Values(map[string]int{"foo": 1, "bar": 2}) // []int{1, 2} From 2642e6debd53f237782e23d3cec6ec1ef4908583 Mon Sep 17 00:00:00 2001 From: Samuel Berthe Date: Mon, 29 Jul 2024 05:32:18 +0200 Subject: [PATCH 20/22] Update README.md --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 55187a29..c5b44297 100644 --- a/README.md +++ b/README.md @@ -1061,7 +1061,7 @@ keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 3}) ### UniqKeys -Creates an array of the unique map keys. +Creates an array of unique map keys. ```go keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3}) @@ -1071,7 +1071,7 @@ keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 3}) // []string{"foo", "bar"} ``` -[[play](https://go.dev/play/p/RyIE6Pb5dVS)] +[[play](https://go.dev/play/p/TPKAb6ILdHk)] ### HasKey @@ -1111,17 +1111,17 @@ values := lo.Values(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 2} Creates an array of unique map values. ```go -values := lo.Values(map[string]int{"foo": 1, "bar": 2}) +values := lo.UniqValues(map[string]int{"foo": 1, "bar": 2}) // []int{1, 2} -values := lo.Values(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3}) +values := lo.UniqValues(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3}) // []int{1, 2, 3} -values := lo.Values(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 2}) +values := lo.UniqValues(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 2}) // []int{1, 2} ``` -[[play](https://go.dev/play/p/RxsJbnaJn3I)] +[[play](https://go.dev/play/p/nf6bXMh7rM3)] ### ValueOr From 954ebe8345bc7fe0023a72ad94e5c635d1ea4f67 Mon Sep 17 00:00:00 2001 From: Samuel Berthe Date: Mon, 29 Jul 2024 05:33:27 +0200 Subject: [PATCH 21/22] Update map.go --- map.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/map.go b/map.go index 9f558add..7d53b94e 100644 --- a/map.go +++ b/map.go @@ -15,7 +15,7 @@ func Keys[K comparable, V any](in ...map[K]V) []K { } // UniqKeys creates an array of unique keys in the map. -// Play: https://go.dev/play/p/RyIE6Pb5dVS +// Play: https://go.dev/play/p/TPKAb6ILdHk func UniqKeys[K comparable, V any](in ...map[K]V) []K { seen := make(map[K]struct{}) result := make([]K, 0) @@ -55,7 +55,7 @@ func Values[K comparable, V any](in ...map[K]V) []V { } // UniqValues creates an array of unique values in the map. -// Play: https://go.dev/play/p/RxsJbnaJn3I +// Play: https://go.dev/play/p/nf6bXMh7rM3 func UniqValues[K comparable, V comparable](in ...map[K]V) []V { seen := make(map[V]struct{}) result := make([]V, 0) From d75619a2b11212ff424d6797cc541829c37475d9 Mon Sep 17 00:00:00 2001 From: Samuel Berthe Date: Mon, 29 Jul 2024 05:35:48 +0200 Subject: [PATCH 22/22] Update map_test.go --- map_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/map_test.go b/map_test.go index 1dd4aa80..25319811 100644 --- a/map_test.go +++ b/map_test.go @@ -101,7 +101,7 @@ func TestUniqValues(t *testing.T) { is.Empty(r2) r3 := UniqValues(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3}) - sort.Ints(r1) + sort.Ints(r3) is.Equal(r3, []int{1, 2, 3}) r4 := UniqValues[string, int]()