优化slice处理

This commit is contained in:
白茶清欢 2024-12-01 15:10:48 +08:00
parent c10486b403
commit d466b7526d
2 changed files with 289 additions and 2 deletions

View File

@ -1,14 +1,15 @@
// Package filter ...
// Package gjson_hack ...
//
// Description : filter ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2024-11-30 19:14
package filter
package gjson_hack
import "errors"
var (
ErrDataIsNotObject = errors.New("data is not an object")
ErrDataIsNotArray = errors.New("data is not an array")
)

View File

@ -9,8 +9,11 @@ package gjson_hack
import (
"errors"
"git.zhangdeman.cn/zhangdeman/consts"
"git.zhangdeman.cn/zhangdeman/util"
"git.zhangdeman.cn/zhangdeman/wrapper"
"github.com/tidwall/gjson"
"strings"
)
// Number 结果转换为数字(int64 / uint64 / float64)
@ -69,3 +72,286 @@ func Float64(gjsonResult gjson.Result) (float64, error) {
}
return float64Result, nil
}
// String 获取字符串值
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 10:55 2024/12/1
func String(sourceValue gjson.Result, defaultValue string) string {
sourceValueStr := defaultValue
if sourceValue.Exists() {
str := sourceValue.String()
if len(str) > 0 {
sourceValueStr = str
}
}
return sourceValueStr
}
// Any 获取任意类型的值
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 11:00 2024/12/1
func Any(sourceValue gjson.Result) (any, error) {
if !sourceValue.Exists() {
return nil, nil
}
// 可能存在精度丢失, 原因 : gjson.Value 内置的转换, int64 超过一定大小会存在丢失精度问题
if sourceValue.Num > 0 || sourceValue.Num < 0 {
// 说明是数字
var res float64
if err := util.ConvertAssign(&res, sourceValue.String()); nil != err {
return nil, err
}
return res, nil
}
if sourceValue.IsObject() {
// 对象不管什么类型的key, 统一转成 map[string]any
res := make(map[string]any)
sourceValue.ForEach(func(k, v gjson.Result) bool {
res[k.String()] = v
return true
})
}
return sourceValue.Value(), nil
}
// getRealDataType ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 14:28 2024/12/1
func getRealDataType(dataType consts.DataType, sourceValue gjson.Result) consts.DataType {
if dataType == consts.DataTypeAny {
if sourceValue.IsObject() {
dataType = consts.DataTypeMapAnyAny
} else if sourceValue.IsArray() {
dataType = consts.DataTypeSliceAny
} else {
if sourceValue.Num != 0 {
dataType = consts.DataTypeFloat
}
}
}
return dataType
}
// SliceInt 获取int list
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 14:43 2024/12/1
func SliceInt(gjsonResult gjson.Result) ([]int64, error) {
if gjsonResult.Value() == nil {
return nil, nil
}
strVal := strings.TrimSpace(gjsonResult.String())
// 任意类型的list
if strings.HasPrefix(strVal, "[") && strings.HasSuffix(strVal, "]") {
// 序列化之后的数组
sliceVal := wrapper.String(strVal).ToInt64Slice()
return sliceVal.Value, sliceVal.Err
}
// 分隔的数组
sliceVal := wrapper.String(strVal).ToInt64Slice(",")
return sliceVal.Value, sliceVal.Err
}
// SliceUint ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 14:58 2024/12/1
func SliceUint(gjsonResult gjson.Result) ([]uint64, error) {
if gjsonResult.Value() == nil {
return nil, nil
}
strVal := strings.TrimSpace(gjsonResult.String())
// 任意类型的list
if strings.HasPrefix(strVal, "[") && strings.HasSuffix(strVal, "]") {
// 序列化之后的数组
sliceVal := wrapper.String(strVal).ToUint64Slice()
return sliceVal.Value, sliceVal.Err
}
// 分隔的数组
sliceVal := wrapper.String(strVal).ToUint64Slice(",")
return sliceVal.Value, sliceVal.Err
}
// SliceFloat ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 14:59 2024/12/1
func SliceFloat(gjsonResult gjson.Result) ([]float64, error) {
if gjsonResult.Value() == nil {
return nil, nil
}
strVal := strings.TrimSpace(gjsonResult.String())
// 任意类型的list
if strings.HasPrefix(strVal, "[") && strings.HasSuffix(strVal, "]") {
// 序列化之后的数组
sliceVal := wrapper.String(strVal).ToFloat64Slice()
return sliceVal.Value, sliceVal.Err
}
// 分隔的数组
sliceVal := wrapper.String(strVal).ToFloat64Slice(",")
return sliceVal.Value, sliceVal.Err
}
// SliceBool ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 15:00 2024/12/1
func SliceBool(gjsonResult gjson.Result) ([]bool, error) {
if gjsonResult.Value() == nil {
return nil, nil
}
strVal := strings.TrimSpace(gjsonResult.String())
// 任意类型的list
if strings.HasPrefix(strVal, "[") && strings.HasSuffix(strVal, "]") {
// 序列化之后的数组
sliceVal := wrapper.String(strVal).ToBoolSlice()
return sliceVal.Value, sliceVal.Err
}
// 分隔的数组
sliceVal := wrapper.String(strVal).ToBoolSlice(",")
return sliceVal.Value, sliceVal.Err
}
// SliceString ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 15:03 2024/12/1
func SliceString(gjsonResult gjson.Result) ([]string, error) {
if gjsonResult.Value() == nil {
return nil, nil
}
strVal := strings.TrimSpace(gjsonResult.String())
// 任意类型的list
if strings.HasPrefix(strVal, "[") && strings.HasSuffix(strVal, "]") {
// 序列化之后的数组
sliceVal := wrapper.String(strVal).ToStringSlice()
return sliceVal.Value, sliceVal.Err
}
// 分隔的数组
sliceVal := wrapper.String(strVal).ToStringSlice(",")
return sliceVal.Value, sliceVal.Err
}
// Value 获取指定的值
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 10:52 2024/12/1
func Value(dataType consts.DataType, sourceValue gjson.Result, defaultValue any) (any, error) {
if !sourceValue.Exists() {
return defaultValue, nil
}
dataType = getRealDataType(dataType, sourceValue)
strVal := wrapper.String(sourceValue.String())
switch dataType {
case consts.DataTypeInt:
return Int(sourceValue)
case consts.DataTypeUint:
return Uint(sourceValue)
case consts.DataTypeFloat:
return Float64(sourceValue)
case consts.DataTypeBool:
boolVal := strVal.ToBool()
return boolVal.Value, boolVal.Err
case consts.DataTypeString:
return sourceValue.String(), nil
case consts.DataTypeAny:
return sourceValue.Value(), nil
case consts.DataTypeSliceAny:
// 任意类型的list
sliceVal := strVal.ToAnySlice()
return sliceVal.Value, sliceVal.Err
case consts.DataTypeSliceInt, consts.DataTypeSliceIntWithChar:
// 任意类型的list
return SliceInt(sourceValue)
case consts.DataTypeSliceUint, consts.DataTypeSliceUintWithChar:
// 任意类型的list
return SliceUint(sourceValue)
case consts.DataTypeSliceFloat, consts.DataTypeSliceFloatWithChar:
// 任意类型的list
return SliceFloat(sourceValue)
case consts.DataTypeSliceBool, consts.DataTypeSliceBoolWithChar:
// 任意类型的list
return SliceBool(sourceValue)
case consts.DataTypeSliceString, consts.DataTypeSliceStringWithChar:
// 任意类型的list
return SliceString(sourceValue)
case consts.DataTypeSliceSlice, consts.DataTypeMapAnyAny:
return nil, errors.New(consts.DataTypeSliceSlice.String() + " : data type is not support")
case consts.DataTypeSliceMapStringAny:
if !sourceValue.IsArray() {
return nil, ErrDataIsNotArray
}
var res []map[string]any
err := strVal.ToStruct(&res)
return res, err
case consts.DataTypeMapStrInt:
if !sourceValue.IsObject() {
return nil, ErrDataIsNotObject
}
var res map[string]int64
err := strVal.ToStruct(&res)
return res, err
case consts.DataTypeMapStrUint:
if !sourceValue.IsObject() {
return nil, ErrDataIsNotObject
}
var res map[string]uint64
err := strVal.ToStruct(&res)
return res, err
case consts.DataTypeMapStrFloat:
if !sourceValue.IsObject() {
return nil, ErrDataIsNotObject
}
var res map[string]float64
err := strVal.ToStruct(&res)
return res, err
case consts.DataTypeMapStrBool:
if !sourceValue.IsObject() {
return nil, ErrDataIsNotObject
}
var res map[string]bool
err := strVal.ToStruct(&res)
return res, err
case consts.DataTypeMapStrAny:
if !sourceValue.IsObject() {
return nil, ErrDataIsNotObject
}
var res map[string]any
err := strVal.ToStruct(&res)
return res, err
case consts.DataTypeMapStrStr:
if !sourceValue.IsObject() {
return nil, ErrDataIsNotObject
}
var res map[string]string
err := strVal.ToStruct(&res)
return res, err
case consts.DataTypeMapStrSlice:
if !sourceValue.IsObject() {
return nil, ErrDataIsNotObject
}
var res map[string][]any
err := strVal.ToStruct(&res)
return res, err
default:
return nil, errors.New("`" + dataType.String() + "` is not support!")
}
}