From 7743ee14ce2beb84f760c4edf3f7b1f28fc7c89b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Fri, 29 Nov 2024 15:51:33 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8C=89=E7=85=A7=E6=A8=A1=E6=9D=BF=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E9=85=8D=E7=BD=AE=E6=95=B0=E7=BB=84,=20=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E8=BF=87=E6=BB=A4=E6=97=B6=E9=80=90=E5=B1=82=E5=B1=95?= =?UTF-8?q?=E5=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gjson_hack/define.go | 13 +++++++++++ gjson_hack/path.go | 52 +++++++++++++++++++++++++++++++++++++---- gjson_hack/path_test.go | 38 ++++++++++++++++++++++++++++++ gjson_hack/precision.go | 2 +- 4 files changed, 100 insertions(+), 5 deletions(-) diff --git a/gjson_hack/define.go b/gjson_hack/define.go index 2c78ff5..855f4cf 100644 --- a/gjson_hack/define.go +++ b/gjson_hack/define.go @@ -29,3 +29,16 @@ type PathResult struct { List []string // 全部路径列表 ValueTable map[string]gjson.Result // 路径对应的值 } + +const ( + ArrayIdxTpl = "{{idx}}" +) + +// ExpendArrayResult 展开数组的结果 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 15:46 2024/11/29 +type ExpendArrayResult struct { + PathList []string `json:"path_list"` // 路径列表 +} diff --git a/gjson_hack/path.go b/gjson_hack/path.go index 6ac654c..3f06cee 100644 --- a/gjson_hack/path.go +++ b/gjson_hack/path.go @@ -8,6 +8,7 @@ package gjson_hack import ( + "errors" "fmt" "github.com/tidwall/gjson" "strings" @@ -93,9 +94,9 @@ func doExpandPath(gjsonResult gjson.Result, rootPath string, hasChildren bool, p // 每一项是对象或者数组 if pathOption.UnfoldArray { // 展开数组 - for idx, itemRes := range arrayList { - doExpandPath(itemRes, rootPath+"."+fmt.Sprintf("%v", idx), true, pathOption, pathResult) - doExpandPath(itemRes, rootPath+".{{idx}}", true, pathOption, pathResult) + for _, itemRes := range arrayList { + // doExpandPath(itemRes, rootPath+"."+fmt.Sprintf("%v", idx), true, pathOption, pathResult) + doExpandPath(itemRes, rootPath+"."+ArrayIdxTpl, true, pathOption, pathResult) } } else { // 不展开数组 @@ -108,7 +109,7 @@ func doExpandPath(gjsonResult gjson.Result, rootPath string, hasChildren bool, p return } } - if strings.HasSuffix(rootPath, ".#") || strings.HasSuffix(rootPath, "{{idx}}") { + if strings.HasSuffix(rootPath, ".#") || strings.HasSuffix(rootPath, ArrayIdxTpl) { // 处理不展开类型数组 return } @@ -122,3 +123,46 @@ func doExpandPath(gjsonResult gjson.Result, rootPath string, hasChildren bool, p } return } + +// ExpandArrayPath 根据真实数据展开数组路径 +// +// 路径中若是包含 {{idx}} 占位符, 说明是需要展开的数组, 根据数组的时机数据, 进行数组的逐级展开 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 11:13 2024/11/29 +func ExpandArrayPath(jsonStr string, pathConfig string, expendArrayResult *ExpendArrayResult) error { + if nil == expendArrayResult { + return errors.New("expendArrayResult can not be nil") + } + if nil == expendArrayResult.PathList { + expendArrayResult.PathList = make([]string, 0) + } + if !strings.Contains(pathConfig, ArrayIdxTpl) { + // 不是数组模板配置, 无需展开 + expendArrayResult.PathList = append(expendArrayResult.PathList, pathConfig) + return nil + } + + pathConfigArr := strings.Split(pathConfig, ArrayIdxTpl) + pathConfigArr[0] = strings.TrimSuffix(pathConfigArr[0], ".") + suffixPathTpl := strings.TrimPrefix(strings.Join(pathConfigArr[1:], ArrayIdxTpl), ".") + valueResult := gjson.Parse(jsonStr).Get(pathConfigArr[0]) + if !valueResult.Exists() { + // 路径不存在, 无需设置具体值 + return nil + } + if !valueResult.IsArray() { + // 不是数组,不要继续再向后展开了 + expendArrayResult.PathList = append(expendArrayResult.PathList, pathConfigArr[0]) + return nil + } + // 继续展开子项 + for idx, _ := range valueResult.Array() { + idxStr := fmt.Sprintf("%v", idx) + if err := ExpandArrayPath(jsonStr, pathConfigArr[0]+"."+idxStr+"."+suffixPathTpl, expendArrayResult); nil != err { + return err + } + } + return nil +} diff --git a/gjson_hack/path_test.go b/gjson_hack/path_test.go index 65f6180..6b2409b 100644 --- a/gjson_hack/path_test.go +++ b/gjson_hack/path_test.go @@ -129,3 +129,41 @@ func TestPathOnlyFinallyPathWithUnfoldArray(t *testing.T) { } } } + +func TestExpandArrayPath(t *testing.T) { + mapData := map[string]any{ + "person_list": []map[string]any{ + {"name": "zhang", "age": 10}, + {"name": "li", "age": 20}, + {"name": "wang", "age": 30}, + }, + "company_info": map[string]any{ + "address": "Beijing", + "email": "xxx@xxx.com", + }, + "sex": "man", + "user_list": [][]map[string]any{ + []map[string]any{ + {"name": "zhang", "age": 10}, + {"name": "li", "age": 20}, + {"name": "wang", "age": 30}, + }, + []map[string]any{ + {"name": "zhang", "age": 10}, + {"name": "li", "age": 20}, + {"name": "wang", "age": 30}, + }, + []map[string]any{ + {"name": "zhang", "age": 10}, + {"name": "li", "age": 20}, + {"name": "wang", "age": 30}, + }, + }, + } + byteData, _ := json.Marshal(mapData) + jsonStr := string(byteData) + // fmt.Println(jsonStr) + var pathExpendRes = &ExpendArrayResult{PathList: nil} + ExpandArrayPath(jsonStr, "user_list.{{idx}}.{{idx}}.age", pathExpendRes) + fmt.Println(pathExpendRes) +} diff --git a/gjson_hack/precision.go b/gjson_hack/precision.go index 0c65e03..1877737 100644 --- a/gjson_hack/precision.go +++ b/gjson_hack/precision.go @@ -1,4 +1,4 @@ -// Package gjson_hack ... +// Package gjson_hack 精确地类型转换 // // Description : gjson_hack ... //