完成数据过主干逻辑,细节健壮性有待继续完善 #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()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user