123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- package maputils
- import (
- "github.com/pkg/errors"
- "strconv"
- "strings"
- )
- const (
- pathSeparator = "."
- )
- func GetValueByPath(m map[string]any, path string) (any, error) {
- if m == nil || strings.TrimSpace(path) == "" {
- return nil, errors.New("没有传递需要查找的数据或路径")
- }
- var retValue any
- var currentFind any
- currentFind = m
- pathParts := strings.Split(path, pathSeparator)
- for _, pathPart := range pathParts {
- if strings.HasPrefix(pathPart, "[") && strings.HasSuffix(pathPart, "]") {
- indexStr := strings.TrimLeft(strings.TrimRight(pathPart, "]"), "[")
- index, err := strconv.Atoi(strings.Trim(indexStr, " "))
- if err != nil {
- return nil, err
- }
- findSlice, ok := currentFind.([]any)
- if ok {
- if index > len(findSlice)-1 {
- retValue = nil
- } else {
- retValue = findSlice[index]
- }
- } else {
- findMapSlice, ok := currentFind.([]map[string]any)
- if !ok {
- return nil, errors.New("对应slice路径的值不是slice: " + pathPart)
- }
- if index > len(findMapSlice)-1 {
- retValue = nil
- } else {
- retValue = findMapSlice[index]
- }
- }
- } else {
- findMap, ok := currentFind.(map[string]any)
- if !ok {
- return nil, errors.New("对应map路径的值不是map[string]any: " + pathPart)
- }
- value, ok := findMap[pathPart]
- if !ok {
- return nil, nil
- }
- retValue = value
- }
- if retValue == nil {
- return nil, nil
- }
- currentFind = retValue
- }
- return retValue, nil
- }
- func GetValueByKey[K comparable, V any](m map[K]any, key K) (V, bool) {
- var zeroValue V
- mapValue, ok := m[key]
- if !ok {
- return zeroValue, false
- }
- v, ok := mapValue.(V)
- if !ok {
- return zeroValue, false
- }
- return v, true
- }
- type SortMap[K comparable, V any] struct {
- sortedKeys []K
- m map[K]V
- }
- func (sortMap *SortMap[K, V]) Range(callback func(index int, key K, value V)) {
- if callback != nil {
- for i, key := range sortMap.sortedKeys {
- callback(i, key, sortMap.m[key])
- }
- }
- }
- func Sort[K comparable, V any](m map[K]V, sortKeysFunc func(keys []K)) *SortMap[K, V] {
- keys := make([]K, 0)
- for key := range m {
- keys = append(keys, key)
- }
- if sortKeysFunc != nil {
- sortKeysFunc(keys)
- }
- return &SortMap[K, V]{
- sortedKeys: keys,
- m: m,
- }
- }
|