From 79c9863144541963c9d541f9b44fbe447cb06c79 Mon Sep 17 00:00:00 2001 From: jingyuexing <19589872+jingyuexing@users.noreply.github.com> Date: Mon, 1 Jan 2024 10:27:39 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20add=20`ForEach`=20?= =?UTF-8?q?=F0=9F=A7=B9=20chore:=20improve=20AccessNested=20function?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- slice.go | 6 ++++++ utils.go | 39 ++++++++++++++++++++++++++++++++------- utils_test.go | 17 +++++++++++++++++ 3 files changed, 55 insertions(+), 7 deletions(-) diff --git a/slice.go b/slice.go index 7e008db..b018db8 100644 --- a/slice.go +++ b/slice.go @@ -88,3 +88,9 @@ func GroupBy[T any, K comparable](slice []T, getKey func(T) K) map[K][]T { return groups } + +func ForEach[T any](slice []T,callback func(value T,key int)){ + for k, v := range slice { + callback(v,k) + } +} diff --git a/utils.go b/utils.go index 54387d8..c799746 100644 --- a/utils.go +++ b/utils.go @@ -75,17 +75,43 @@ func pathParse(target string) []string { return obj } -func AccessNested(data map[string]interface{}, path string, delimiter string) interface{} { +func AccessNested(data any, path string, delimiter string) any { keys := strings.Split(path, delimiter) - value := data + value := reflect.ValueOf(data) + + if value.Kind() == reflect.Pointer { + value = reflect.Indirect(value) + } + for _, key := range keys { - if val, ok := value[key]; ok { - value = val.(map[string]interface{}) - } else { + if !value.IsValid() { + return nil + } + + switch value.Kind() { + case reflect.Pointer: + value = reflect.Indirect(value) + case reflect.Map: + mapValue := value.MapIndex(reflect.ValueOf(key)) + if !mapValue.IsValid() { + return nil + } + value = mapValue + case reflect.Struct: + field := value.FieldByName(key) + if !field.IsValid() { + return nil + } + value = field + default: return nil } } - return value + + if value.IsValid() && value.CanInterface() { + return value.Interface() + } + return nil } func GetPathValue(raw string, realPath string) map[string]string { @@ -170,7 +196,6 @@ func Map2Struct(source map[string]any, bindingTarget any) { } } - func TimeDuration(duration string) (time.Time, error) { const ( SECOND uint64 = 1 diff --git a/utils_test.go b/utils_test.go index 6041c5f..6daab31 100644 --- a/utils_test.go +++ b/utils_test.go @@ -132,3 +132,20 @@ func TestEmit(t *testing.T){ } } + +func TestAccessNested(t *testing.T) { + type S struct { + A struct { + B int + } + } + k := &S{ + A: struct{B int}{ + B:33, + }, + } + value := utils.AccessNested(k,"A.B",".") + if value.(int) != 33 { + t.Error("not pass") + } +}