增加obj2slice,以及数据类型检测

This commit is contained in:
白茶清欢 2022-01-23 00:53:34 +08:00
parent a768d758b2
commit 749abad4ad
2 changed files with 76 additions and 0 deletions

View File

@ -8,8 +8,11 @@
package json_tool
import (
"reflect"
"strings"
"github.com/pkg/errors"
"github.com/tidwall/gjson"
"github.com/Jeffail/gabs"
@ -59,11 +62,35 @@ func (df *DataFilter) Filter() (string, error) {
jsonObject *gabs.Container
err error
)
// 记录 obj => slice 的数据类型
obg2slice := make(map[string]string)
// 创建数据的根结点
jsonObject = gabs.New()
for _, item := range df.filterRule {
if strings.Contains(item.SourceKey, "[]") {
// 数组, 特殊处理
// 1. 判断数据源数组深度与目标数组深度是否一致
continue
}
// 目标位置, 是一个数组
if strings.HasSuffix(item.MapKey, "[]") {
realMapKey := strings.ReplaceAll(item.MapKey, ".[]", "")
if exist := jsonObject.Exists(realMapKey); !exist {
if _, err = jsonObject.ArrayP(realMapKey); nil != err {
return "", err
}
}
valueResult := gjson.Get(df.source, item.SourceKey)
dataType := df.getValueType(valueResult)
if _, exist := obg2slice[realMapKey]; !exist {
obg2slice[realMapKey] = dataType
}
if dataType != obg2slice[realMapKey] {
return "", errors.New(realMapKey + " 预期写入的字段数据类型不一致")
}
if err = jsonObject.ArrayAppend(valueResult.Value(), realMapKey); nil != err {
return "", err
}
continue
}
sourceSearchResult := gjson.Get(df.source, item.SourceKey)
@ -81,3 +108,19 @@ func (df *DataFilter) Filter() (string, error) {
}
return jsonObject.String(), nil
}
// getValueType 获取数据类型
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2022/1/23 12:45 AM
func (df *DataFilter) getValueType(valueResult gjson.Result) string {
dataType := reflect.TypeOf(valueResult.Value()).String()
if strings.Contains(dataType, "int") {
return "int64"
}
if strings.Contains(dataType, "float") {
return "float64"
}
return dataType
}

View File

@ -206,3 +206,36 @@ func TestDataFilter(t *testing.T) {
filter := NewDataFilter(string(byteData), rule)
fmt.Println(filter.Filter())
}
// TestDataFilterForObiToSlice ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2022/1/23 12:06 AM
func TestDataFilterForObiToSlice(t *testing.T) {
source := map[string]interface{}{
"name": "zhangdeman",
"age": 18,
"height": 180,
"extra": map[string]interface{}{
"age": 18,
"height": 180,
"slice": []int{1, 2, 3},
},
"slice_data": []int{1, 2, 3},
"map": map[string]interface{}{"a": 1, "b": 2, "c": 4},
"table": []map[string]interface{}{
{"name": "alex", "age": 18, "number": 1},
{"name": "bob", "age": 28, "number": 2},
{"name": "bob", "age": 28, "number": 2, "list": []int{1, 2, 3}},
},
}
rule := []FilterDataRule{
// {SourceKey: "name", MapKey: "slice.[]", DefaultValue: "用户姓名默认值"},
{SourceKey: "age", MapKey: "slice.[]", DefaultValue: "用户姓名默认值"},
{SourceKey: "height", MapKey: "slice.[]", DefaultValue: "用户姓名默认值"},
}
byteData, _ := json.Marshal(source)
filter := NewDataFilter(string(byteData), rule)
fmt.Println(filter.Filter())
}