...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package mxj
19
20 import (
21 "errors"
22 "strings"
23 )
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 func (mv Map) NewMap(keypairs ...string) (Map, error) {
39 n := make(map[string]interface{}, 0)
40 if len(keypairs) == 0 {
41 return n, nil
42 }
43
44
45 var oldKey, newKey string
46 var path []string
47 for _, v := range keypairs {
48 if len(v) == 0 {
49 continue
50 }
51
52
53 vv := strings.Split(v, ":")
54 if len(vv) > 2 {
55 return n, errors.New("oldKey:newKey keypair value not valid - " + v)
56 }
57 if len(vv) == 1 {
58 oldKey, newKey = vv[0], vv[0]
59 } else {
60 oldKey, newKey = vv[0], vv[1]
61 }
62 strings.TrimSpace(oldKey)
63 strings.TrimSpace(newKey)
64 if i := strings.Index(newKey, "*"); i > -1 {
65 return n, errors.New("newKey value cannot contain wildcard character - " + v)
66 }
67 if i := strings.Index(newKey, "["); i > -1 {
68 return n, errors.New("newKey value cannot contain indexed arrays - " + v)
69 }
70 if oldKey == "" || newKey == "" {
71 return n, errors.New("oldKey or newKey is not specified - " + v)
72 }
73
74
75 oldVal, err := mv.ValuesForPath(oldKey)
76 if err != nil {
77 return n, err
78 }
79 if len(oldVal) == 0 {
80 continue
81 }
82
83
84 path = strings.Split(newKey, ".")
85 if path[len(path)-1] == "" {
86 path = path[:len(path)-1]
87 }
88
89 addNewVal(&n, path, oldVal)
90 }
91
92 return n, nil
93 }
94
95
96 func addNewVal(n *map[string]interface{}, path []string, val []interface{}) {
97
98 var newVal interface{}
99 if len(val) == 1 {
100 newVal = val[0]
101 } else {
102 newVal = interface{}(val)
103 }
104
105
106 m := (*n)
107 var k string
108 lp := len(path) - 1
109 for i := 0; i < len(path); i++ {
110 k = path[i]
111 if i == lp {
112 break
113 }
114 var nm map[string]interface{}
115 switch m[k].(type) {
116 case nil:
117 nm = make(map[string]interface{}, 0)
118 m[k] = interface{}(nm)
119 m = m[k].(map[string]interface{})
120 case map[string]interface{}:
121
122 m = m[k].(map[string]interface{})
123 case []interface{}:
124
125
126
127
128
129 a := make([]interface{}, 0)
130 var foundmap bool
131 for _, vv := range m[k].([]interface{}) {
132 switch vv.(type) {
133 case nil:
134 if foundmap {
135 a = append(a, vv)
136 continue
137 }
138 nm = make(map[string]interface{}, 0)
139 a = append(a, interface{}(nm))
140 foundmap = true
141 case map[string]interface{}:
142 if foundmap {
143 a = append(a, vv)
144 continue
145 }
146 nm = vv.(map[string]interface{})
147 a = append(a, vv)
148 foundmap = true
149 default:
150 a = append(a, vv)
151 }
152 }
153
154 if !foundmap {
155 nm = make(map[string]interface{}, 0)
156 a = append(a, interface{}(nm))
157 }
158 m[k] = interface{}(a)
159 m = nm
160 default:
161 aa := make([]interface{}, 0)
162 nm = make(map[string]interface{}, 0)
163 aa = append(aa, m[k], nm)
164 m[k] = interface{}(aa)
165 m = nm
166 }
167 }
168
169
170
171 v := m[k]
172 switch v.(type) {
173 case nil:
174 m[k] = newVal
175 case []interface{}:
176 a := m[k].([]interface{})
177 a = append(a, newVal)
178 m[k] = interface{}(a)
179 default:
180 a := make([]interface{}, 0)
181 a = append(a, v, newVal)
182 m[k] = interface{}(a)
183 }
184 }
185
View as plain text