mapsort.go 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  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, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind,
  23. protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
  24. return keys[i].Int() < keys[j].Int()
  25. case protoreflect.Uint32Kind, protoreflect.Fixed32Kind,
  26. protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
  27. return keys[i].Uint() < keys[j].Uint()
  28. case protoreflect.StringKind:
  29. return keys[i].String() < keys[j].String()
  30. default:
  31. panic("invalid kind: " + keyKind.String())
  32. }
  33. })
  34. for _, key := range keys {
  35. if !f(key, mapv.Get(key)) {
  36. break
  37. }
  38. }
  39. }