diff --git a/maps/maps.go b/maps/maps.go index ad112e7..2d01703 100644 --- a/maps/maps.go +++ b/maps/maps.go @@ -2,9 +2,11 @@ package maps // ToValues returns an array of just the values of the input Map. func ToValues[In any, Key comparable](arr map[Key]In) []In { - out := make([]In, 0, len(arr)) - for _, elem := range arr { - out = append(out, elem) + i := 0 + out := make([]In, len(arr)) + for _, value := range arr { + out[i] = value + i++ } return out } @@ -12,9 +14,22 @@ func ToValues[In any, Key comparable](arr map[Key]In) []In { // ToSlice applies the function to each element of the input map, and returns an // array of the results. func ToSlice[M ~map[K]V, K comparable, V, R any](items M, f func(K, V) R) []R { - out := make([]R, 0, len(items)) + i := 0 + out := make([]R, len(items)) for k, v := range items { - out = append(out, f(k, v)) + out[i] = f(k, v) + i++ + } + return out +} + +// ToKeys returns an array of the keys of the input Map. +func ToKeys[In any, Key comparable](arr map[Key]In) []Key { + i := 0 + out := make([]Key, len(arr)) + for key := range arr { + out[i] = key + i++ } return out } diff --git a/maps/maps_test.go b/maps/maps_test.go index 8fcd495..df2a94c 100644 --- a/maps/maps_test.go +++ b/maps/maps_test.go @@ -13,6 +13,31 @@ const benchmarkArrayLength = 10_000 var benchResult []int +func TestToKeys(t *testing.T) { + t.Run( + "String Keys", func(t *testing.T) { + test := map[string]int{ + "one": 1, + "two": 2, + "three": 3, + } + keys := ToKeys(test) + require.ElementsMatch(t, []string{"one", "two", "three"}, keys) + }, + ) + t.Run( + "Int Keys", func(t *testing.T) { + test := map[int]string{ + 1: "one", + 2: "two", + 3: "three", + } + keys := ToKeys(test) + require.ElementsMatch(t, []int{1, 2, 3}, keys) + }, + ) +} + func TestToValues(t *testing.T) { nums := map[string]int{ "one": 1, @@ -44,7 +69,7 @@ func TestToSlice(t *testing.T) { func BenchmarkToValues(b *testing.B) { arr := make(map[int]int, benchmarkArrayLength) for i := range arr { - arr[i] = rand.Int() + arr[i] = rand.Int() //nolint:gosec } var r []int @@ -57,7 +82,7 @@ func BenchmarkToValues(b *testing.B) { func BenchmarkToSlice(b *testing.B) { arr := make(map[int]int, benchmarkArrayLength) for i := range arr { - arr[i] = rand.Int() + arr[i] = rand.Int() //nolint:gosec } var r []int for i := 0; i < b.N; i++ { @@ -94,3 +119,16 @@ func ExampleToSlice() { fmt.Println(results) // Output: [1 in text is one 2 in text is two 3 in text is three] } + +func ExampleToKeys() { + nums := map[string]int{ + "a": 1, + "b": 2, + "c": 3, + } + results := ToKeys(nums) + + sort.Strings(results) // order is not guaranteed for map keys + fmt.Println(results) + // Output: [a b c] +}