完成数据过主干逻辑,细节健壮性有待继续完善 #4
							
								
								
									
										100
									
								
								tool/gabs.go
									
									
									
									
									
								
							
							
						
						
									
										100
									
								
								tool/gabs.go
									
									
									
									
									
								
							| @ -19,6 +19,11 @@ import ( | ||||
| 	"github.com/tidwall/sjson" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	// virtualRoot 虚拟根节点 | ||||
| 	virtualRoot = "__VIRTUAL_ROOT__" | ||||
| ) | ||||
|  | ||||
| // FilterOption 过滤选项 | ||||
| // | ||||
| // Author : go_developer@163.com<白茶清欢> | ||||
| @ -54,17 +59,36 @@ func NewDataFilter(source string, filterRule []*FilterDataRule, filterOption *Fi | ||||
| 		filterOption.LogInstance = os.Stdout | ||||
| 		log.SetOutput(filterOption.LogInstance) | ||||
| 	} | ||||
| 	df := &DataFilter{ | ||||
| 		source:        source, | ||||
| 		filterRule:    make([]*FilterDataRule, 0), | ||||
| 		rewriteResult: "{}", | ||||
| 		filterOption:  filterOption, | ||||
| 	} | ||||
| 	// 去除末尾的 .[] | ||||
| 	for _, item := range filterRule { | ||||
| 		item.MapKey = strings.TrimRight(item.MapKey, ".[]") | ||||
| 		item.SourceKey = strings.TrimRight(item.SourceKey, ".[]") | ||||
| 		mapIsArr := df.isArrPath(item.MapKey) | ||||
| 		if !mapIsArr { | ||||
| 			df.filterRule = append(df.filterRule, item) | ||||
| 			continue | ||||
| 		} | ||||
| 		if len(df.getArrPathList(item.SourceKey)) < len(df.getArrPathList(item.MapKey)) { | ||||
| 			panic("map result deep more than source data deep") | ||||
| 		} | ||||
| 		formatRes := make([]*FilterDataRule, 0) | ||||
| 		r, _ := df.unfoldSameDeepArr(item.SourceKey, item.MapKey, "", "") | ||||
| 		for _, itemUnfoldResult := range r { | ||||
| 			itemMapArr := strings.Split(itemUnfoldResult.MapKey, ".") | ||||
| 			if len(itemMapArr) != len(strings.Split(item.MapKey, ".")) { | ||||
| 				continue | ||||
| 			} | ||||
| 			formatRes = append(formatRes, itemUnfoldResult) | ||||
| 		} | ||||
| 		df.filterRule = append(df.filterRule, formatRes...) | ||||
| 	} | ||||
| 	return &DataFilter{ | ||||
| 		source:        source, | ||||
| 		filterRule:    filterRule, | ||||
| 		rewriteResult: "{}", | ||||
| 		filterOption:  filterOption, | ||||
| 	} | ||||
| 	return df | ||||
| } | ||||
|  | ||||
| // DataFilter 数据过滤 | ||||
| @ -120,8 +144,8 @@ func (df *DataFilter) Filter() (string, error) { | ||||
| 			// 数组深度一致 | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 	} | ||||
| 	df.logPrint(logLevelDebug, "过滤结果", df.rewriteResult) | ||||
| 	return df.rewriteResult, nil | ||||
| } | ||||
|  | ||||
| @ -134,22 +158,72 @@ func (df *DataFilter) isArrPath(path string) bool { | ||||
| 	return strings.Contains(path, "[]") | ||||
| } | ||||
|  | ||||
| // setSameDeepArr 设置同深度的数组 | ||||
| // setSameDeepArr 展开同深度数组的 | ||||
| // | ||||
| // Author : go_developer@163.com<白茶清欢> | ||||
| // | ||||
| // Date : 12:19 2023/9/2 | ||||
| func (df *DataFilter) setSameDeepArr(sourceVal string, sourcePath string, mapPath string) error { | ||||
| func (df *DataFilter) unfoldSameDeepArr(sourcePath string, mapPath string, sourceRootPath string, mapRootPath string) ([]*FilterDataRule, error) { | ||||
| 	df.logPrint(logLevelDebug, " 同深数组展开", sourceRootPath, mapRootPath) | ||||
| 	result := make([]*FilterDataRule, 0) | ||||
| 	if len(sourcePath) == 0 { | ||||
| 		return result, nil | ||||
| 	} | ||||
| 	sourcePathArr := df.getArrPathList(sourcePath) | ||||
| 	mapPathArr := df.getArrPathList(mapPath) | ||||
| 	for idx, itemSourcePath := range sourcePathArr { | ||||
| 		sourceValueArr := gjson.Get(sourceVal, sourcePath).Array() | ||||
| 	if 1 == len(mapPathArr) { | ||||
| 		sourceKey := sourceRootPath + "." + sourcePathArr[0] | ||||
| 		if len(sourcePathArr[0:]) > 0 { | ||||
| 			sourceKey = sourceRootPath + "." + strings.Join(sourcePathArr[0:], ".[].") | ||||
| 		} | ||||
| 		result = append(result, &FilterDataRule{ | ||||
| 			SourceKey:    sourceKey, | ||||
| 			MapKey:       mapRootPath + "." + mapPathArr[0], | ||||
| 			DefaultValue: nil, | ||||
| 			WithDefault:  false, | ||||
| 		}) | ||||
| 		return result, nil | ||||
| 	} | ||||
| 	return nil | ||||
| 	// 数组 展开 | ||||
| 	for idx := 0; idx < len(mapPathArr); idx++ { | ||||
| 		if len(sourceRootPath) > 0 { | ||||
| 			sourceRootPath = fmt.Sprintf("%v.%v", sourceRootPath, sourcePathArr[idx]) | ||||
| 		} else { | ||||
| 			sourceRootPath = sourcePathArr[idx] | ||||
| 		} | ||||
| 		if len(mapRootPath) > 0 { | ||||
| 			mapRootPath = fmt.Sprintf("%v.%v", mapRootPath, mapPathArr[idx]) | ||||
| 		} else { | ||||
| 			mapRootPath = mapPathArr[idx] | ||||
| 		} | ||||
| 		valList := gjson.Get(df.source, sourceRootPath) | ||||
| 		if valList.Value() == nil { | ||||
| 			continue | ||||
| 		} | ||||
| 		for i := 0; i < len(valList.Array()); i++ { | ||||
| 			result = append(result, &FilterDataRule{ | ||||
| 				SourceKey:    sourceRootPath, | ||||
| 				MapKey:       mapRootPath, | ||||
| 				DefaultValue: nil, | ||||
| 				WithDefault:  false, | ||||
| 			}) | ||||
| 			r, e := df.unfoldSameDeepArr( | ||||
| 				strings.Join(sourcePathArr[idx+1:], "[]"), | ||||
| 				strings.Join(mapPathArr[idx+1:], "[]"), | ||||
| 				fmt.Sprintf("%v.%v", sourceRootPath, i), | ||||
| 				fmt.Sprintf("%v.%v", mapRootPath, i), | ||||
| 			) | ||||
| 			if nil != e { | ||||
| 				return nil, e | ||||
| 			} | ||||
| 			result = append(result, r...) | ||||
| 		} | ||||
| 	} | ||||
| 	return result, nil | ||||
| } | ||||
|  | ||||
| // a.[].b.[].c.[].d | ||||
| // e.[].f.[].g | ||||
| // g | ||||
| // getDataAsSlice 抽取制定深度,生成list | ||||
| // | ||||
| // Author : go_developer@163.com<白茶清欢> | ||||
|  | ||||
| @ -10,6 +10,7 @@ package json_tool | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| 	"testing" | ||||
|  | ||||
| 	"git.zhangdeman.cn/zhangdeman/serialize" | ||||
| @ -140,3 +141,145 @@ func TestDataFilter_sourceArrAndMapSingle(t *testing.T) { | ||||
| 	} | ||||
| 	fmt.Println(df.Filter()) | ||||
| } | ||||
|  | ||||
| // TestDataFilter_unfoldSameDeepArr 测试展开同深度数组 | ||||
| // | ||||
| // Author : go_developer@163.com<白茶清欢> | ||||
| // | ||||
| // Date : 15:42 2023/9/2 | ||||
| func TestDataFilter_unfoldSameDeepArr(t *testing.T) { | ||||
| 	source := map[string]interface{}{ | ||||
| 		"list": []interface{}{ | ||||
| 			map[string]interface{}{ | ||||
| 				"name": "1", | ||||
| 				"age":  "2", | ||||
| 				"list_test": []interface{}{ | ||||
| 					map[string]interface{}{ | ||||
| 						"a": "a", | ||||
| 						"b": "b", | ||||
| 						"c": map[string]interface{}{ | ||||
| 							"a": "1", | ||||
| 						}, | ||||
| 						"d": []int{1, 2, 3}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			map[string]interface{}{ | ||||
| 				"name": "3", | ||||
| 				"age":  "4", | ||||
| 				"list_test": []interface{}{ | ||||
| 					map[string]interface{}{ | ||||
| 						"a": "a1", | ||||
| 						"b": "b1", | ||||
| 						"c": map[string]interface{}{ | ||||
| 							"a": "a", | ||||
| 						}, | ||||
| 						"d": []int{1, 2, 3}, | ||||
| 					}, | ||||
| 					map[string]interface{}{ | ||||
| 						"a": "a2", | ||||
| 						"b": "b1", | ||||
| 						"c": map[string]interface{}{ | ||||
| 							"a": "a", | ||||
| 						}, | ||||
| 						"d": []int{1, 2, 3}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			map[string]interface{}{ | ||||
| 				"name": "5", | ||||
| 				"age":  "6", | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	df := &DataFilter{ | ||||
| 		source: serialize.JSON.MarshalForString(source), | ||||
| 		filterRule: []*FilterDataRule{ | ||||
| 			{SourceKey: "list.[].list_test.[].a", MapKey: "a_list.[].a.[].val", DefaultValue: "[]", WithDefault: true}, | ||||
| 			{SourceKey: "list.[].list_test.[].b", MapKey: "b_list.[].b.[].val", DefaultValue: "[]", WithDefault: true}, | ||||
| 			{SourceKey: "list.[].list_test.[].c", MapKey: "c_list.[].c.[].val", DefaultValue: "[]", WithDefault: true}, | ||||
| 			{SourceKey: "list.[].list_test.[].d", MapKey: "d_list.[].d.[].val", DefaultValue: "[]", WithDefault: true}, | ||||
| 		}, | ||||
| 		filterOption: &FilterOption{DebugModel: true}, | ||||
| 	} | ||||
| 	r, _ := df.unfoldSameDeepArr("list.[].list_test.[].a", "a_list.[].a_not_equal_list", "", "") | ||||
|  | ||||
| 	formatRes := make([]*FilterDataRule, 0) | ||||
| 	for _, item := range r { | ||||
| 		itemMapArr := strings.Split(item.MapKey, ".") | ||||
| 		if len(itemMapArr) != 3 && len(itemMapArr) != 5 { | ||||
| 			continue | ||||
| 		} | ||||
| 		formatRes = append(formatRes, item) | ||||
| 	} | ||||
| 	fmt.Println(serialize.JSON.MarshalForString(formatRes)) | ||||
| } | ||||
|  | ||||
| // TestDataFilter_filterSameDeepArr ... | ||||
| // | ||||
| // Author : go_developer@163.com<白茶清欢> | ||||
| // | ||||
| // Date : 20:41 2023/9/2 | ||||
| func TestDataFilter_filterSameDeepArr(t *testing.T) { | ||||
| 	source := map[string]interface{}{ | ||||
| 		"list": []interface{}{ | ||||
| 			map[string]interface{}{ | ||||
| 				"name": "1", | ||||
| 				"age":  "2", | ||||
| 				"list_test": []interface{}{ | ||||
| 					map[string]interface{}{ | ||||
| 						"a": "a", | ||||
| 						"b": "b", | ||||
| 						"c": map[string]interface{}{ | ||||
| 							"a": "1", | ||||
| 						}, | ||||
| 						"d": []int{1, 2, 3}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			map[string]interface{}{ | ||||
| 				"name": "3", | ||||
| 				"age":  "4", | ||||
| 				"list_test": []interface{}{ | ||||
| 					map[string]interface{}{ | ||||
| 						"a": "a1", | ||||
| 						"b": "b1", | ||||
| 						"c": map[string]interface{}{ | ||||
| 							"a": "a", | ||||
| 						}, | ||||
| 						"d": []int{1, 2, 3}, | ||||
| 					}, | ||||
| 					map[string]interface{}{ | ||||
| 						"a": "a2", | ||||
| 						"b": "b1", | ||||
| 						"c": map[string]interface{}{ | ||||
| 							"a": "a", | ||||
| 						}, | ||||
| 						"d": []int{1, 2, 3}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			map[string]interface{}{ | ||||
| 				"name": "5", | ||||
| 				"age":  "6", | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	filterRuleList := []*FilterDataRule{ | ||||
| 		{SourceKey: "name", MapKey: "user_name", DefaultValue: "油猴", WithDefault: true}, | ||||
| 		{SourceKey: "extra.age", MapKey: "user_age", DefaultValue: "18", WithDefault: true}, | ||||
| 		{SourceKey: "slice", MapKey: "user_index", DefaultValue: "[4,5,6]", WithDefault: true}, | ||||
| 		{SourceKey: "none", MapKey: "none_default", DefaultValue: map[string]interface{}{"a": "a"}, WithDefault: true}, | ||||
| 		{SourceKey: "extra", MapKey: "extra_object", DefaultValue: map[string]interface{}{"a": "a"}, WithDefault: true}, | ||||
| 		{SourceKey: "list.[].list_test.[].a", MapKey: "a_list.[].a.[].val", DefaultValue: "[]", WithDefault: true}, | ||||
| 		{SourceKey: "list.[].list_test.[].a", MapKey: "a_list.[].a_not_equal_list", DefaultValue: "[]", WithDefault: true}, | ||||
| 		{SourceKey: "list.[].list_test.[].a", MapKey: "a_list.[].a.[].val1", DefaultValue: "[]", WithDefault: true}, | ||||
| 		{SourceKey: "list.[].list_test.[].b", MapKey: "b_list.[].b.[].val", DefaultValue: "[]", WithDefault: true}, | ||||
| 		{SourceKey: "list.[].list_test.[].c", MapKey: "c_list.[].c.[].val", DefaultValue: "[]", WithDefault: true}, | ||||
| 		{SourceKey: "list.[].list_test.[].d", MapKey: "d_list.[].d.[].val", DefaultValue: "[]", WithDefault: true}, | ||||
| 	} | ||||
| 	filterOption := &FilterOption{DebugModel: true} | ||||
|  | ||||
| 	df := NewDataFilter(serialize.JSON.MarshalForString(source), filterRuleList, filterOption) | ||||
| 	_, _ = df.Filter() | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user