mapsort.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. // Copyright 2019 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // Package mapsort provides sorted access to maps.
  5. package mapsort
  6. import (
  7. "sort"
  8. "google.golang.org/protobuf/reflect/protoreflect"
  9. )
  10. // Range iterates over every map entry in sorted key order,
  11. // calling f for each key and value encountered.
  12. func Range(mapv protoreflect.Map, keyKind protoreflect.Kind, f func(protoreflect.MapKey, protoreflect.Value) bool) {
  13. var keys []protoreflect.MapKey
  14. mapv.Range(func(key protoreflect.MapKey, _ protoreflect.Value) bool {
  15. keys = append(keys, key)
  16. return true
  17. })
  18. sort.Slice(keys, func(i, j int) bool {
  19. switch keyKind {
  20. case protoreflect.BoolKind:
  21. return !keys[i].Bool() && keys[j].Bool()
  22. case protoreflect.Int32Kind,
  23. protoreflect.Sint32Kind,
  24. protoreflect.Sfixed32Kind,
  25. protoreflect.Int64Kind,
  26. protoreflect.Sint64Kind,
  27. protoreflect.Sfixed64Kind:
  28. return keys[i].Int() < keys[j].Int()
  29. case protoreflect.Uint32Kind,
  30. protoreflect.Fixed32Kind,
  31. protoreflect.Uint64Kind,
  32. protoreflect.Fixed64Kind:
  33. return keys[i].Uint() < keys[j].Uint()
  34. default:
  35. return keys[i].String() < keys[j].String()
  36. }
  37. })
  38. for _, key := range keys {
  39. if !f(key, mapv.Get(key)) {
  40. break
  41. }
  42. }
  43. }