From 7bba11eb2eab9adbedc1239a0d8c7fd3a6fbdaaa Mon Sep 17 00:00:00 2001 From: mmetc <92726601+mmetc@users.noreply.github.com> Date: Tue, 2 Jul 2024 14:29:21 +0200 Subject: [PATCH] maptools/SortedKeysNoCase() (#17) --- maptools/sort.go | 24 +++++++++++++++++++++++- maptools/sort_test.go | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/maptools/sort.go b/maptools/sort.go index 7088adc..89a931f 100644 --- a/maptools/sort.go +++ b/maptools/sort.go @@ -1,6 +1,9 @@ package maptools -import "sort" +import ( + "sort" + "strings" +) func SortedKeys[V any](m map[string]V) []string { keys := make([]string, 0, len(m)) @@ -12,3 +15,22 @@ func SortedKeys[V any](m map[string]V) []string { return keys } + +func SortedKeysNoCase[V any](m map[string]V) []string { + keys := make([]string, 0, len(m)) + for k := range m { + keys = append(keys, k) + } + + sort.Slice(keys, func(i, j int) bool { + li, lj := strings.ToLower(keys[i]), strings.ToLower(keys[j]) + if li == lj { + // differ only by case, sort by original key + // will have uppercase first + return keys[i] < keys[j] + } + return li < lj + }) + + return keys +} diff --git a/maptools/sort_test.go b/maptools/sort_test.go index 0043ec6..c949c7a 100644 --- a/maptools/sort_test.go +++ b/maptools/sort_test.go @@ -40,3 +40,43 @@ func TestSortedKeys(t *testing.T) { }) } } + +func TestSortedKeysNoCase(t *testing.T) { + tests := []struct { + name string + m map[string]int + want []string + }{ + { + name: "empty map", + m: map[string]int{}, + want: []string{}, + }, + { + name: "single element", + m: map[string]int{"a": 1}, + want: []string{"a"}, + }, + { + name: "multiple elements with different cases", + m: map[string]int{"b": 2, "A": 1, "C": 3}, + want: []string{"A", "b", "C"}, + }, + { + name: "elements with same values and different cases", + m: map[string]int{"b": 2, "A": 2, "c": 2}, + want: []string{"A", "b", "c"}, + }, + { + name: "mixed case elements", + m: map[string]int{"Banana": 1, "apple": 2, "Cherry": 3, "banana": 4, "Apple": 5, "cherry": 6}, + want: []string{"Apple", "apple", "Banana", "banana", "Cherry", "cherry"}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.want, SortedKeysNoCase(tt.m)) + }) + } +}