diff --git a/json_tool/gabs.go b/json_tool/gabs.go index 0340693..25ef7d4 100644 --- a/json_tool/gabs.go +++ b/json_tool/gabs.go @@ -35,7 +35,7 @@ type FilterDataRule struct { // Author : go_developer@163.com<白茶清欢> // // Date : 2022/1/22 9:50 PM -func NewDataFilter(source string, filterRule []FilterDataRule) *DataFilter { +func NewDataFilter(source string, filterRule []*FilterDataRule) *DataFilter { return &DataFilter{ source: source, filterRule: filterRule, @@ -48,8 +48,9 @@ func NewDataFilter(source string, filterRule []FilterDataRule) *DataFilter { // // Date : 2022/1/22 9:20 PM type DataFilter struct { - source string - filterRule []FilterDataRule + source string + filterRule []*FilterDataRule + itemKeyToSlice bool } // Filter 数据过滤 @@ -62,6 +63,8 @@ func (df *DataFilter) Filter() (string, error) { jsonObject *gabs.Container err error ) + // 格式化映射规则 + df.formatRule() // 记录 obj => slice 的数据类型 obg2slice := make(map[string]string) // 创建数据的根结点 @@ -70,19 +73,15 @@ func (df *DataFilter) Filter() (string, error) { if df.pathIsArrayValue(item.SourceKey) { // 数组, 特殊处理 // 0. 判断目标路径是否为数组 - if !df.pathIsArrayValue(item.MapKey) { - // 目标路径不是数组, 转换为支持list, 后续逻辑会自动提取为list数组 - item.MapKey = item.MapKey + ".[]" - } else { - // 1. 判断数据源数组深度与目标数组深度是否一致 - sourcePathArr := strings.Split(item.SourceKey, ".[].") - mapPathArr := strings.Split(item.MapKey, ".[].") - if len(sourcePathArr) != len(mapPathArr) { - return "", errors.New("slice转化原始数据深度与目标数据深度不一致") - } - continue + // 1. 判断数据源数组深度与目标数组深度是否一致 + sourcePathArr := strings.Split(item.SourceKey, ".[].") + mapPathArr := strings.Split(item.MapKey, ".[].") + if len(sourcePathArr) != len(mapPathArr) { + return "", errors.New("slice转化原始数据深度与目标数据深度不一致") } + continue } + // 数据源路径不识数组, 多个key写入到同一个map key, 并且map key 不是以[]结尾, 自动格式化 // 目标位置, 是一个数组 if df.pathIsArrayValue(item.MapKey) { realMapKey := strings.ReplaceAll(item.MapKey, ".[]", "") @@ -120,6 +119,15 @@ func (df *DataFilter) Filter() (string, error) { return jsonObject.String(), nil } +// UserItemToSlice 支持多个独立的字段合并到slice中 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 3:27 PM 2022/1/24 +func (df *DataFilter) UserItemToSlice() { + df.itemKeyToSlice = true +} + // getValueType 获取数据类型 // // Author : go_developer@163.com<白茶清欢> @@ -144,3 +152,37 @@ func (df *DataFilter) getValueType(valueResult gjson.Result) string { func (df *DataFilter) pathIsArrayValue(path string) bool { return strings.Contains(path, "[]") } + +// formatRule 格式化映射规则 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2:43 PM 2022/1/24 +func (df *DataFilter) formatRule() { + mapKeyCnt := make(map[string]int) + for _, item := range df.filterRule { + // source 为数组, map 不是 + if df.pathIsArrayValue(item.SourceKey) { + if !df.pathIsArrayValue(item.MapKey) { + item.MapKey = item.MapKey + ".[]" + } else { + // source 是数组, map也是数组, 检测数组层级匹配 + } + } else { + if df.pathIsArrayValue(item.MapKey) { + continue + } + // source 不是数组, map 也不是 + if !df.itemKeyToSlice { + continue + } + mapKeyCnt[item.MapKey]++ + } + } + // 多个source指向一个map,自动转化为list + for _, item := range df.filterRule { + if mapKeyCnt[item.MapKey] > 1 { + item.MapKey = item.MapKey + ".[]" + } + } +} diff --git a/json_tool/json_test.go b/json_tool/json_test.go index bf548c3..11e1171 100644 --- a/json_tool/json_test.go +++ b/json_tool/json_test.go @@ -191,7 +191,7 @@ func TestDataFilter(t *testing.T) { {"name": "bob", "age": 28, "number": 2, "list": []int{1, 2, 3}}, }, } - rule := []FilterDataRule{ + rule := []*FilterDataRule{ {SourceKey: "name", MapKey: "user_name", DefaultValue: "用户姓名默认值"}, {SourceKey: "name", MapKey: "username", DefaultValue: "用户姓名默认值"}, {SourceKey: "name", MapKey: "user.name", DefaultValue: "用户姓名默认值"}, @@ -230,12 +230,13 @@ func TestDataFilterForObiToSlice(t *testing.T) { {"name": "bob", "age": 28, "number": 2, "list": []int{1, 2, 3}}, }, } - rule := []FilterDataRule{ + rule := []*FilterDataRule{ // {SourceKey: "name", MapKey: "slice.[]", DefaultValue: "用户姓名默认值"}, - {SourceKey: "age", MapKey: "slice.[]", DefaultValue: "用户姓名默认值"}, - {SourceKey: "height", MapKey: "slice.[]", DefaultValue: "用户姓名默认值"}, + {SourceKey: "age", MapKey: "slice", DefaultValue: "用户姓名默认值"}, + {SourceKey: "height", MapKey: "slice", DefaultValue: "用户姓名默认值"}, } byteData, _ := json.Marshal(source) filter := NewDataFilter(string(byteData), rule) + filter.UserItemToSlice() fmt.Println(filter.Filter()) }