diff --git a/maputil/check.go b/maputil/check.go index d2c10ff2b..1f3194465 100644 --- a/maputil/check.go +++ b/maputil/check.go @@ -21,7 +21,25 @@ func HasKey(mp, key any) (ok bool) { return } -// HasAllKeys check of the given map. +// HasOneKey check of the given map. return the first exist key +func HasOneKey(mp any, keys ...any) (ok bool, key any) { + rftVal := reflect.Indirect(reflect.ValueOf(mp)) + if rftVal.Kind() != reflect.Map { + return + } + + for _, key = range keys { + for _, keyRv := range rftVal.MapKeys() { + if reflects.IsEqual(keyRv.Interface(), key) { + return true, key + } + } + } + + return false, nil +} + +// HasAllKeys check of the given map. return the first not exist key func HasAllKeys(mp any, keys ...any) (ok bool, noKey any) { rftVal := reflect.Indirect(reflect.ValueOf(mp)) if rftVal.Kind() != reflect.Map { diff --git a/maputil/convert.go b/maputil/convert.go index 5a351ffdd..4ded4cfde 100644 --- a/maputil/convert.go +++ b/maputil/convert.go @@ -1,10 +1,12 @@ package maputil import ( + "errors" "reflect" "strings" "github.com/gookit/goutil/arrutil" + "github.com/gookit/goutil/comdef" "github.com/gookit/goutil/reflects" "github.com/gookit/goutil/strutil" ) @@ -33,18 +35,33 @@ func CombineToSMap(keys, values []string) SMap { return arrutil.CombineToSMap(keys, values) } +// CombineToMap combine two any slice to map[K]V. alias of arrutil.CombineToMap +func CombineToMap[K comdef.SortedType, V any](keys []K, values []V) map[K]V { + return arrutil.CombineToMap(keys, values) +} + // ToAnyMap convert map[TYPE1]TYPE2 to map[string]any func ToAnyMap(mp any) map[string]any { + amp, _ := TryAnyMap(mp) + return amp +} + +// TryAnyMap convert map[TYPE1]TYPE2 to map[string]any +func TryAnyMap(mp any) (map[string]any, error) { + if aMp, ok := mp.(map[string]any); ok { + return aMp, nil + } + rv := reflect.Indirect(reflect.ValueOf(mp)) if rv.Kind() != reflect.Map { - panic("not a map value") + return nil, errors.New("input is not a map value") } anyMp := make(map[string]any, rv.Len()) for _, key := range rv.MapKeys() { anyMp[key.String()] = rv.MapIndex(key).Interface() } - return anyMp + return anyMp, nil } // HTTPQueryString convert map[string]any data to http query string. diff --git a/maputil/convert_test.go b/maputil/convert_test.go index b5ecf70d1..44dac1f95 100644 --- a/maputil/convert_test.go +++ b/maputil/convert_test.go @@ -38,9 +38,13 @@ func TestToAnyMap(t *testing.T) { assert.Len(t, mp, 2) assert.Eq(t, "v0", mp["a"]) - assert.Panics(t, func() { - maputil.ToAnyMap(123) - }) + src1 := map[string]any{"a": "v0", "b": "23"} + mp = maputil.ToAnyMap(src1) + assert.Len(t, mp, 2) + assert.Eq(t, "v0", mp["a"]) + + _, err := maputil.TryAnyMap(123) + assert.Err(t, err) } func TestHTTPQueryString(t *testing.T) { diff --git a/maputil/maputil.go b/maputil/maputil.go index 7becfa7bf..4e047c289 100644 --- a/maputil/maputil.go +++ b/maputil/maputil.go @@ -33,7 +33,7 @@ func SimpleMerge(src, dst map[string]any) map[string]any { return dst } -// func DeepMerge(src, dst map[string]any, deep int) map[string]any { +// func DeepMerge(src, dst map[string]any, deep int) map[string]any { TODO // } // MergeSMap simple merge two string map. merge src to dst map