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) {