fix(template): make map helper ordering deterministic

This commit is contained in:
SG Command
2026-07-19 15:19:33 +02:00
parent 784dc1f0da
commit c2def00bcf
2 changed files with 119 additions and 5 deletions
+32 -5
View File
@@ -1,7 +1,9 @@
package reflectutil
import (
"fmt"
"reflect"
"sort"
"strings"
)
@@ -134,7 +136,7 @@ func MapKeys(i interface{}) []interface{} {
return []interface{}{}
}
keys := v.MapKeys()
keys := sortedMapKeys(v)
result := make([]interface{}, len(keys))
for i, key := range keys {
result[i] = key.Interface()
@@ -155,14 +157,39 @@ func MapValues(i interface{}) []interface{} {
return []interface{}{}
}
result := make([]interface{}, 0, v.Len())
iter := v.MapRange()
for iter.Next() {
result = append(result, iter.Value().Interface())
keys := sortedMapKeys(v)
result := make([]interface{}, 0, len(keys))
for _, key := range keys {
result = append(result, v.MapIndex(key).Interface())
}
return result
}
func sortedMapKeys(v reflect.Value) []reflect.Value {
keys := v.MapKeys()
sort.SliceStable(keys, func(i, j int) bool {
return mapKeyLess(keys[i], keys[j])
})
return keys
}
func mapKeyLess(a, b reflect.Value) bool {
switch a.Kind() {
case reflect.String:
return a.String() < b.String()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return a.Int() < b.Int()
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return a.Uint() < b.Uint()
case reflect.Float32, reflect.Float64:
return a.Float() < b.Float()
case reflect.Bool:
return !a.Bool() && b.Bool()
default:
return fmt.Sprint(a.Interface()) < fmt.Sprint(b.Interface())
}
}
// MapGet safely gets a value from a map by key
// Returns nil if key doesn't exist or not a map
func MapGet(m interface{}, key interface{}) interface{} {