maputils.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. package maputils
  2. import (
  3. "errors"
  4. "strconv"
  5. "strings"
  6. )
  7. const (
  8. pathSeparator = "."
  9. )
  10. // GetValueByPath 通过路径查询map的值,常用查找unmarshal到map的json或者yaml中的值
  11. // 参数:
  12. // m: key是string类型的map,值可以是任意类型,如果map下的值还是map,则map的key必须为string类型
  13. // path: 路径,如foo1.foo1_sub.[0],key为foo1的值是一个map[string]any,foo1_sub对应的值是一个slice,如果需要取slice的某一个值,可以用[n]获取
  14. // 返回值:
  15. // 对应的值和错误
  16. func GetValueByPath(m map[string]any, path string) (any, error) {
  17. if m == nil || strings.TrimSpace(path) == "" {
  18. return nil, errors.New("没有传递需要查找的数据或路径")
  19. }
  20. var retValue any
  21. var currentFind any
  22. currentFind = m
  23. pathParts := strings.Split(path, pathSeparator)
  24. for _, pathPart := range pathParts {
  25. if strings.HasPrefix(pathPart, "[") && strings.HasSuffix(pathPart, "]") {
  26. indexStr := strings.TrimLeft(strings.TrimRight(pathPart, "]"), "[")
  27. index, err := strconv.Atoi(strings.Trim(indexStr, " "))
  28. if err != nil {
  29. return nil, err
  30. }
  31. findSlice, ok := currentFind.([]any)
  32. if ok {
  33. if index > len(findSlice)-1 {
  34. retValue = nil
  35. } else {
  36. retValue = findSlice[index]
  37. }
  38. } else {
  39. findMapSlice, ok := currentFind.([]map[string]any)
  40. if !ok {
  41. return nil, errors.New("对应slice路径的值不是slice: " + pathPart)
  42. }
  43. if index > len(findMapSlice)-1 {
  44. retValue = nil
  45. } else {
  46. retValue = findMapSlice[index]
  47. }
  48. }
  49. } else {
  50. findMap, ok := currentFind.(map[string]any)
  51. if !ok {
  52. return nil, errors.New("对应map路径的值不是map[string]any: " + pathPart)
  53. }
  54. value, ok := findMap[pathPart]
  55. if !ok {
  56. return nil, nil
  57. }
  58. retValue = value
  59. }
  60. if retValue == nil {
  61. return nil, nil
  62. }
  63. currentFind = retValue
  64. }
  65. return retValue, nil
  66. }
  67. // GetValueByKey 通过key查询map的值
  68. // 模板参数:
  69. // K是map的key的类型,V是map值的类型
  70. // 参数:
  71. // m: 从这个map获取值
  72. // key: map的key
  73. // 返回值:
  74. // 对应的值和获取是否成功,失败可能有两个原因:对应的key不存在或者V类型转换失败
  75. func GetValueByKey[K comparable, V any](m map[K]any, key K) (V, bool) {
  76. var zeroValue V
  77. mapValue, ok := m[key]
  78. if !ok {
  79. return zeroValue, false
  80. }
  81. v, ok := mapValue.(V)
  82. if !ok {
  83. return zeroValue, false
  84. }
  85. return v, true
  86. }