Skip to content

Commit 636dca7

Browse files
committed
增加了Map的Set和Append函数,能设置值
1 parent bdbba5f commit 636dca7

File tree

3 files changed

+308
-107
lines changed

3 files changed

+308
-107
lines changed

conv_map.go

+168-101
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ import (
55
json "github.com/json-iterator/go"
66
"regexp"
77
"strings"
8+
"sync"
89
)
910

1011
// NewMap 新建数据
1112
// 递归(惰性,用到才解析)获取所有可以解析数据
1213
func NewMap(i interface{}, codec ...codec.Interface) *Map {
14+
//一般用NewMap之后,肯定会获取值的,固直接decode
1315
return newMap(i, codec...).decode()
1416
}
1517

@@ -18,7 +20,7 @@ func newMap(i interface{}, codec ...codec.Interface) *Map {
1820
return val
1921
}
2022
m := &Map{Var: New(i)}
21-
if len(codec) > 0 {
23+
if len(codec) > 0 && codec[0] != nil {
2224
m.codec = codec[0]
2325
}
2426
return m
@@ -27,142 +29,175 @@ func newMap(i interface{}, codec ...codec.Interface) *Map {
2729
// Map deep 惰性解析 DMap
2830
// 万次解析0.09s
2931
type Map struct {
30-
*Var //值
31-
Extend //继承
32-
valMap map[string]*Map //map
33-
valList []*Map //list
34-
de bool //是否已解析
35-
codec codec.Interface //编解码
32+
*Var //值
33+
Extend //继承
34+
object map[string]*Map //对象实例
35+
array []*Map //数组实例
36+
codec codec.Interface //编解码
37+
once sync.Once //惰性加载,解析一次
38+
hasSet bool //设置了新数据
3639
}
3740

38-
func (this *Map) IsDefault(key ...string) bool {
39-
if len(key) == 0 {
40-
return this.Var.IsDefault()
41-
}
42-
return this.Get(key[0]).IsDefault(key[1:]...)
43-
}
44-
45-
func (this *Map) IsNumber(key ...string) bool {
46-
if len(key) == 0 {
47-
return this.Var.IsNumber()
48-
}
49-
return this.Get(key[0]).IsNumber(key[1:]...)
41+
// GetVar 实现Extend的接口,继承Extend的接口
42+
func (this *Map) GetVar(key string) *Var {
43+
return this.Get(key).Var
5044
}
5145

52-
func (this *Map) IsString(key ...string) bool {
53-
if len(key) == 0 {
54-
return this.Var.IsString()
46+
// Map 获取对象map,不安全,不推荐使用
47+
func (this *Map) Map() map[string]*Map {
48+
for _, v := range this.object {
49+
v.decode()
5550
}
56-
return this.Get(key[0]).IsString(key[1:]...)
51+
return this.object
5752
}
5853

59-
func (this *Map) IsInt(key ...string) bool {
60-
if len(key) == 0 {
61-
return this.Var.IsInt()
54+
// List 获取数组,不安全,不推荐使用
55+
func (this *Map) List() []*Map {
56+
for _, v := range this.array {
57+
v.decode()
6258
}
63-
return this.Get(key[0]).IsInt(key[1:]...)
59+
return this.array
6460
}
6561

66-
func (this *Map) IsFloat(key ...string) bool {
67-
if len(key) == 0 {
68-
return this.Var.IsFloat()
62+
// Get 获取Map,可以根据分隔符来获取更深入的数据
63+
// 分隔符.和小数冲突,现在暂时不支持查询key是小数的对象或者key有.和[]
64+
// 例如使用key(a.b[0]) 可以从 {"a":{"b":[0,1]}} 得到0的Map
65+
func (this *Map) Get(key string) *Map {
66+
data := this
67+
for _, v := range this.getKeys(key) {
68+
switch k := v.(type) {
69+
case string:
70+
data = data.getObject(k, false)
71+
case int:
72+
data = data.getArray(k)
73+
}
6974
}
70-
return this.Get(key[0]).IsFloat(key[1:]...)
75+
return data.refresh()
7176
}
7277

73-
func (this *Map) IsBool(key ...string) bool {
74-
if len(key) == 0 {
75-
return this.Var.IsBool()
78+
// Set 设置数据,会覆盖原先的数据,
79+
// key可以使用分割符号.和[],分别对应对象和数组,例 a.b[1].c[1][3]
80+
// 分隔符.和小数冲突,现在暂时不支持查询key是小数的对象或者key有.和[]
81+
// 例如使用Set("a.b[0]",100) 可以使 {"a":{"b":[0,1]}} 变成 {"a":{"b":[100,1]}}
82+
// 假如对象key不存在,会自动添加
83+
// 如果数组的下标不存在,则不会自动添加,例如设置了下标100,补充99个nil值不是很合理
84+
// 如果设置了nil,对应json的null
85+
func (this *Map) Set(key string, value interface{}) *Map {
86+
data := this
87+
for _, v := range this.getKeys(key) {
88+
//所有的父级都打上标记,方便后续判断
89+
data.hasSet = true
90+
switch k := v.(type) {
91+
case string:
92+
data = data.getObject(k, true)
93+
case int:
94+
data = data.getArray(k)
95+
}
7696
}
77-
return this.Get(key[0]).IsBool(key[1:]...)
97+
*data = *newMap(value, this.codec) //覆盖原先的Map
98+
return this
7899
}
79100

80-
func (this *Map) IsTime(key ...string) bool {
81-
if len(key) == 0 {
82-
return this.Var.IsTime()
101+
// Append 追加元素,只对数组有效
102+
// key可以使用分割符号.和[],分别对应对象和数组,例 a.b[1].c[1][3]
103+
// 分隔符.和小数冲突,现在暂时不支持查询key是小数的对象或者key有.和[]
104+
// 例如 {"a":{"n":1},"b":[0,1]} 使用Append("b",3,4)后,得到 {"a":{"n":1},"b":[0,1,3,4]}
105+
// 但是使用Append("a",3,4)后是无变化的,因为a是对象,可以使用Set("a",[]int{0,1,3,4})得到一样的结果
106+
// 如果设置了nil,对应json的null
107+
func (this *Map) Append(key string, value ...interface{}) *Map {
108+
data := this
109+
for _, v := range this.getKeys(key) {
110+
//所有的父级都打上标记,方便后续判断
111+
data.hasSet = true
112+
switch k := v.(type) {
113+
case string:
114+
data = data.getObject(k, true)
115+
case int:
116+
data = data.getArray(k)
117+
}
83118
}
84-
return this.Get(key[0]).IsTime(key[1:]...)
85-
}
86-
87-
func (this *Map) IsArray(key ...string) bool {
88-
if len(key) == 0 {
89-
return this.Var.IsArray()
119+
if len(data.object) == 0 {
120+
//假如不是对象的情况下生效
121+
for _, v := range value {
122+
data.array = append(data.array, newMap(v, this.codec))
123+
}
124+
data.hasSet = true
125+
data.Var.Set(data.encode())
90126
}
91-
return this.Get(key[0]).IsArray(key[1:]...)
127+
return this
92128
}
93129

94-
func (this *Map) IsPointer(key ...string) bool {
95-
if len(key) == 0 {
96-
return this.Var.IsPointer()
97-
}
98-
return this.Get(key[0]).IsPointer(key[1:]...)
130+
// String 重构下Var的String函数,针对Set/Append后的惰性更新
131+
func (this *Map) String(def ...string) string {
132+
this.refresh()
133+
return this.Var.String(def...)
99134
}
100135

101-
func (this *Map) IsNil(key ...string) bool {
102-
if len(key) == 0 {
103-
return this.Var.IsNil()
136+
// refresh 刷新,因为是惰性加载/更新,固有个刷新函数
137+
// 正常情况是使用不到,除非直接
138+
func (this *Map) refresh() *Map {
139+
if this.hasSet {
140+
this.Var.Set(this.encode())
141+
this.hasSet = false
104142
}
105-
return this.Get(key[0]).IsNil(key[1:]...)
143+
return this
106144
}
107145

108-
func (this *Map) GoString() string {
109-
return this.Var.String()
110-
}
146+
/*
111147
112-
func (this *Map) GetVar(key string) *Var {
113-
return this.Get(key).Var
114-
}
115148
116-
func (this *Map) Map() map[string]*Map {
117-
for _, v := range this.valMap {
118-
v.decode()
119-
}
120-
return this.valMap
121-
}
122149
123-
func (this *Map) List() []*Map {
124-
for _, v := range this.valList {
125-
v.decode()
126-
}
127-
return this.valList
128-
}
150+
*/
129151

130-
func (this *Map) Get(key string) *Map {
131-
data := this
152+
// 获取对象的key或者数组的下标,用类型来区分,字符表示对象的key,数字表示数字的下标
153+
// 先分割.,再正则匹配[0-9]+,例如 a.key[1][0] ,得到 {"a","key",1,0}
154+
func (this *Map) getKeys(key string) []interface{} {
155+
keys := []interface{}(nil)
132156
for _, v := range strings.Split(key, ".") {
133-
list := regexp.MustCompile(`\[[0-9]+\]`).FindAllString(v, -1)
134-
lengthAll := 0
135-
for i, k := range list {
136-
length := len(k)
137-
lengthAll += length
138-
list[i] = k[1 : length-1]
139-
}
140-
v = v[:len(v)-lengthAll]
141-
if len(v) > 0 {
142-
data = data.getMap(v)
157+
indexList := []interface{}(nil)
158+
length := 0
159+
for _, k := range regexp.MustCompile(`\[[0-9]+\]`).FindAllString(v, -1) {
160+
length += len(k)
161+
//去除[]后的数字,即数组的下标
162+
indexList = append(indexList, Int(k[1:len(k)-1]))
143163
}
144-
for _, k := range list {
145-
data = data.getList(Int(k))
164+
if vKey := v[:len(v)-length]; len(vKey) > 0 {
165+
//对象的key,例 key[1][0] 中间的key
166+
keys = append(keys, v[:len(v)-length])
146167
}
168+
//数组的下标
169+
keys = append(keys, indexList...)
147170
}
148-
return data
171+
return keys
149172
}
150173

151-
func (this *Map) getMap(key string) *Map {
152-
data, ok := this.valMap[key]
174+
// 根据key获取对象
175+
func (this *Map) getObject(key string, setIfNotExist bool) *Map {
176+
data, ok := this.object[key]
153177
if ok {
154178
return data.decode()
155179
}
156-
return NewMap(nil, this.codec)
180+
m := NewMap(nil, this.codec)
181+
if setIfNotExist {
182+
this.object[key] = m
183+
}
184+
return m
157185
}
158186

159-
func (this *Map) getList(idx int) *Map {
160-
if idx < len(this.valList) {
161-
return this.valList[idx].decode()
187+
// 根据下标获取数组的元素,支持python的负数下标,
188+
// 例如-1表示获取数组的最后一个元素
189+
func (this *Map) getArray(idx int) *Map {
190+
if idx >= 0 && idx < len(this.array) {
191+
return this.array[idx].decode()
192+
}
193+
//对负数的支持,例如-1表示获取数组的最后一个元素,参考python
194+
if idx < 0 && -idx <= len(this.array) {
195+
return this.array[len(this.array)+idx].decode()
162196
}
163197
return NewMap(nil, this.codec)
164198
}
165199

200+
// 获取编解码函数
166201
func (this *Map) getParse() func(data []byte, v interface{}) error {
167202
if this.codec == nil {
168203
if codec.Default != nil {
@@ -174,39 +209,71 @@ func (this *Map) getParse() func(data []byte, v interface{}) error {
174209
}
175210

176211
func (this *Map) decode() *Map {
177-
if !this.de {
212+
this.once.Do(func() {
178213
parse := this.getParse()
179-
this.valMap = make(map[string]*Map)
214+
this.object = make(map[string]*Map)
180215
if !this.Var.IsNil() {
181216
switch val := this.Var.Val().(type) {
182217
case map[string]interface{}:
183218
for i, v := range val {
184-
this.valMap[i] = newMap(v, codec.Json)
219+
this.object[i] = newMap(v, codec.Json)
220+
}
221+
case map[interface{}]interface{}:
222+
for i, v := range val {
223+
this.object[String(i)] = newMap(v, codec.Json)
185224
}
186225
case []interface{}:
187226
for _, v := range val {
188-
this.valList = append(this.valList, newMap(v, codec.Json))
227+
this.array = append(this.array, newMap(v, codec.Json))
189228
}
190229
default:
191230
m := make(map[string]interface{})
192231
bs := []byte(this.Var.String())
193232
if err := parse(bs, &m); err == nil {
194233
for i, v := range m {
195-
this.valMap[i] = newMap(v, codec.Json)
234+
this.object[String(i)] = newMap(v, codec.Json)
196235
}
197236
} else {
198237
var list []interface{}
199238
if err := parse(bs, &list); err == nil {
200239
for _, v := range list {
201-
this.valList = append(this.valList, newMap(v, codec.Json))
240+
this.array = append(this.array, newMap(v, codec.Json))
202241
}
203242
}
204243
}
205244

206245
}
207246
}
208247
this.Extend = NewExtend(this)
209-
this.de = true
210-
}
248+
})
211249
return this
212250
}
251+
252+
func (this *Map) encode() interface{} {
253+
254+
//判断是否设置过新值,没解析直接取var的值
255+
if !this.hasSet {
256+
return this.Var.Val()
257+
}
258+
259+
if len(this.array) > 0 {
260+
//数组
261+
list := []interface{}(nil)
262+
for _, v := range this.array {
263+
list = append(list, v.encode())
264+
}
265+
return list
266+
}
267+
268+
if len(this.object) > 0 {
269+
//对象
270+
object := map[string]interface{}{}
271+
for k, v := range this.object {
272+
object[k] = v.encode()
273+
}
274+
return object
275+
}
276+
277+
return this.Var.Val()
278+
279+
}

0 commit comments

Comments
 (0)