Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changes/20251015131907.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:sparkles: `collection` Add functions for converting maps to slices in a stable/ordered way
19 changes: 19 additions & 0 deletions utils/collection/parseLists.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
package collection

import (
"cmp"
"fmt"
"maps"
"slices"
"strings"
"unicode"
Expand Down Expand Up @@ -170,3 +172,20 @@ func ConvertMapToCommaSeparatedList[K comparable, V any](pairs map[K]V) string {
func ConvertMapToCommaSeparatedPairsList[K comparable, V any](pairs map[K]V, pairSeparator string) string {
return ConvertSliceToCommaSeparatedList[string](ConvertMapToPairSlice[K, V](pairs, pairSeparator))
}

// ConvertMapToOrderedSlice converts a map to a slice and ensures that the ordering will always be the same
func ConvertMapToOrderedSlice[K cmp.Ordered, V any](pairs map[K]V) []string {
if len(pairs) == 0 {
return nil
}
slice := make([]string, 0, len(pairs)*2)
for _, key := range slices.Sorted(maps.Keys(pairs)) {
slice = append(slice, fmt.Sprintf("%v", key), fmt.Sprintf("%v", pairs[key]))
}
return slice
}

// ConvertMapToOrderedCommaSeparatedList converts a map to a commar-separated list and ensures that the ordering will always be the same
func ConvertMapToOrderedCommaSeparatedList[K cmp.Ordered, V any](pairs map[K]V) string {
return ConvertSliceToCommaSeparatedList[string](ConvertMapToOrderedSlice[K, V](pairs))
}
9 changes: 9 additions & 0 deletions utils/collection/parseLists_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ func TestParseCommaSeparatedPairListToMap(t *testing.T) {
{"Normal 10", ",, ,, ,", map[string]string{}, nil, "+"},
{"Normal 11", ConvertMapToCommaSeparatedPairsList[string, string](randomMap, "/"), randomMap, nil, "/"},
{"Normal 12", ConvertMapToCommaSeparatedPairsList[string, string](randomMap, " "), randomMap, nil, " "},
{"Normal 13", ConvertMapToOrderedCommaSeparatedList[string, string](randomMap), randomMap, nil, ","},
{"Bad 1", "one", nil, commonerrors.ErrInvalid, "+"},
{"Bad 1", "one, two, three", nil, commonerrors.ErrInvalid, "+"},
{"Bad 2", "one element with spaces", nil, commonerrors.ErrInvalid, "+"},
Expand All @@ -195,3 +196,11 @@ func TestParseCommaSeparatedPairListToMap(t *testing.T) {
})
}
}

func TestConvertMapToCommaSeparatedListStable(t *testing.T) {
testMap := map[string]string{"hello": "world", "adrien": "cabarbaye", "fish": "cake", "apple": "pie"}
expected := "adrien,cabarbaye,apple,pie,fish,cake,hello,world"
for range 100 {
assert.Equal(t, expected, ConvertMapToOrderedCommaSeparatedList(testMap))
}
}
Loading