1package objx 2 3/* 4 MSI (map[string]interface{} and []map[string]interface{}) 5*/ 6 7// MSI gets the value as a map[string]interface{}, returns the optionalDefault 8// value or a system default object if the value is the wrong type. 9func (v *Value) MSI(optionalDefault ...map[string]interface{}) map[string]interface{} { 10 if s, ok := v.data.(map[string]interface{}); ok { 11 return s 12 } 13 if s, ok := v.data.(Map); ok { 14 return map[string]interface{}(s) 15 } 16 if len(optionalDefault) == 1 { 17 return optionalDefault[0] 18 } 19 return nil 20} 21 22// MustMSI gets the value as a map[string]interface{}. 23// 24// Panics if the object is not a map[string]interface{}. 25func (v *Value) MustMSI() map[string]interface{} { 26 if s, ok := v.data.(Map); ok { 27 return map[string]interface{}(s) 28 } 29 return v.data.(map[string]interface{}) 30} 31 32// MSISlice gets the value as a []map[string]interface{}, returns the optionalDefault 33// value or nil if the value is not a []map[string]interface{}. 34func (v *Value) MSISlice(optionalDefault ...[]map[string]interface{}) []map[string]interface{} { 35 if s, ok := v.data.([]map[string]interface{}); ok { 36 return s 37 } 38 39 s := v.ObjxMapSlice() 40 if s == nil { 41 if len(optionalDefault) == 1 { 42 return optionalDefault[0] 43 } 44 return nil 45 } 46 47 result := make([]map[string]interface{}, len(s)) 48 for i := range s { 49 result[i] = s[i].Value().MSI() 50 } 51 return result 52} 53 54// MustMSISlice gets the value as a []map[string]interface{}. 55// 56// Panics if the object is not a []map[string]interface{}. 57func (v *Value) MustMSISlice() []map[string]interface{} { 58 if s := v.MSISlice(); s != nil { 59 return s 60 } 61 62 return v.data.([]map[string]interface{}) 63} 64 65// IsMSI gets whether the object contained is a map[string]interface{} or not. 66func (v *Value) IsMSI() bool { 67 _, ok := v.data.(map[string]interface{}) 68 if !ok { 69 _, ok = v.data.(Map) 70 } 71 return ok 72} 73 74// IsMSISlice gets whether the object contained is a []map[string]interface{} or not. 75func (v *Value) IsMSISlice() bool { 76 _, ok := v.data.([]map[string]interface{}) 77 if !ok { 78 _, ok = v.data.([]Map) 79 if !ok { 80 s, ok := v.data.([]interface{}) 81 if ok { 82 for i := range s { 83 switch s[i].(type) { 84 case Map: 85 case map[string]interface{}: 86 default: 87 return false 88 } 89 } 90 return true 91 } 92 } 93 } 94 return ok 95} 96 97// EachMSI calls the specified callback for each object 98// in the []map[string]interface{}. 99// 100// Panics if the object is the wrong type. 101func (v *Value) EachMSI(callback func(int, map[string]interface{}) bool) *Value { 102 for index, val := range v.MustMSISlice() { 103 carryon := callback(index, val) 104 if !carryon { 105 break 106 } 107 } 108 return v 109} 110 111// WhereMSI uses the specified decider function to select items 112// from the []map[string]interface{}. The object contained in the result will contain 113// only the selected items. 114func (v *Value) WhereMSI(decider func(int, map[string]interface{}) bool) *Value { 115 var selected []map[string]interface{} 116 v.EachMSI(func(index int, val map[string]interface{}) bool { 117 shouldSelect := decider(index, val) 118 if !shouldSelect { 119 selected = append(selected, val) 120 } 121 return true 122 }) 123 return &Value{data: selected} 124} 125 126// GroupMSI uses the specified grouper function to group the items 127// keyed by the return of the grouper. The object contained in the 128// result will contain a map[string][]map[string]interface{}. 129func (v *Value) GroupMSI(grouper func(int, map[string]interface{}) string) *Value { 130 groups := make(map[string][]map[string]interface{}) 131 v.EachMSI(func(index int, val map[string]interface{}) bool { 132 group := grouper(index, val) 133 if _, ok := groups[group]; !ok { 134 groups[group] = make([]map[string]interface{}, 0) 135 } 136 groups[group] = append(groups[group], val) 137 return true 138 }) 139 return &Value{data: groups} 140} 141 142// ReplaceMSI uses the specified function to replace each map[string]interface{}s 143// by iterating each item. The data in the returned result will be a 144// []map[string]interface{} containing the replaced items. 145func (v *Value) ReplaceMSI(replacer func(int, map[string]interface{}) map[string]interface{}) *Value { 146 arr := v.MustMSISlice() 147 replaced := make([]map[string]interface{}, len(arr)) 148 v.EachMSI(func(index int, val map[string]interface{}) bool { 149 replaced[index] = replacer(index, val) 150 return true 151 }) 152 return &Value{data: replaced} 153} 154 155// CollectMSI uses the specified collector function to collect a value 156// for each of the map[string]interface{}s in the slice. The data returned will be a 157// []interface{}. 158func (v *Value) CollectMSI(collector func(int, map[string]interface{}) interface{}) *Value { 159 arr := v.MustMSISlice() 160 collected := make([]interface{}, len(arr)) 161 v.EachMSI(func(index int, val map[string]interface{}) bool { 162 collected[index] = collector(index, val) 163 return true 164 }) 165 return &Value{data: collected} 166} 167 168/* 169 ObjxMap ((Map) and [](Map)) 170*/ 171 172// ObjxMap gets the value as a (Map), returns the optionalDefault 173// value or a system default object if the value is the wrong type. 174func (v *Value) ObjxMap(optionalDefault ...(Map)) Map { 175 if s, ok := v.data.((Map)); ok { 176 return s 177 } 178 if s, ok := v.data.(map[string]interface{}); ok { 179 return s 180 } 181 if len(optionalDefault) == 1 { 182 return optionalDefault[0] 183 } 184 return New(nil) 185} 186 187// MustObjxMap gets the value as a (Map). 188// 189// Panics if the object is not a (Map). 190func (v *Value) MustObjxMap() Map { 191 if s, ok := v.data.(map[string]interface{}); ok { 192 return s 193 } 194 return v.data.((Map)) 195} 196 197// ObjxMapSlice gets the value as a [](Map), returns the optionalDefault 198// value or nil if the value is not a [](Map). 199func (v *Value) ObjxMapSlice(optionalDefault ...[](Map)) [](Map) { 200 if s, ok := v.data.([]Map); ok { 201 return s 202 } 203 204 if s, ok := v.data.([]map[string]interface{}); ok { 205 result := make([]Map, len(s)) 206 for i := range s { 207 result[i] = s[i] 208 } 209 return result 210 } 211 212 s, ok := v.data.([]interface{}) 213 if !ok { 214 if len(optionalDefault) == 1 { 215 return optionalDefault[0] 216 } 217 return nil 218 } 219 220 result := make([]Map, len(s)) 221 for i := range s { 222 switch s[i].(type) { 223 case Map: 224 result[i] = s[i].(Map) 225 case map[string]interface{}: 226 result[i] = New(s[i]) 227 default: 228 return nil 229 } 230 } 231 return result 232} 233 234// MustObjxMapSlice gets the value as a [](Map). 235// 236// Panics if the object is not a [](Map). 237func (v *Value) MustObjxMapSlice() [](Map) { 238 if s := v.ObjxMapSlice(); s != nil { 239 return s 240 } 241 return v.data.([](Map)) 242} 243 244// IsObjxMap gets whether the object contained is a (Map) or not. 245func (v *Value) IsObjxMap() bool { 246 _, ok := v.data.((Map)) 247 if !ok { 248 _, ok = v.data.(map[string]interface{}) 249 } 250 return ok 251} 252 253// IsObjxMapSlice gets whether the object contained is a [](Map) or not. 254func (v *Value) IsObjxMapSlice() bool { 255 _, ok := v.data.([](Map)) 256 if !ok { 257 _, ok = v.data.([]map[string]interface{}) 258 if !ok { 259 s, ok := v.data.([]interface{}) 260 if ok { 261 for i := range s { 262 switch s[i].(type) { 263 case Map: 264 case map[string]interface{}: 265 default: 266 return false 267 } 268 } 269 return true 270 } 271 } 272 } 273 274 return ok 275} 276 277// EachObjxMap calls the specified callback for each object 278// in the [](Map). 279// 280// Panics if the object is the wrong type. 281func (v *Value) EachObjxMap(callback func(int, Map) bool) *Value { 282 for index, val := range v.MustObjxMapSlice() { 283 carryon := callback(index, val) 284 if !carryon { 285 break 286 } 287 } 288 return v 289} 290 291// WhereObjxMap uses the specified decider function to select items 292// from the [](Map). The object contained in the result will contain 293// only the selected items. 294func (v *Value) WhereObjxMap(decider func(int, Map) bool) *Value { 295 var selected [](Map) 296 v.EachObjxMap(func(index int, val Map) bool { 297 shouldSelect := decider(index, val) 298 if !shouldSelect { 299 selected = append(selected, val) 300 } 301 return true 302 }) 303 return &Value{data: selected} 304} 305 306// GroupObjxMap uses the specified grouper function to group the items 307// keyed by the return of the grouper. The object contained in the 308// result will contain a map[string][](Map). 309func (v *Value) GroupObjxMap(grouper func(int, Map) string) *Value { 310 groups := make(map[string][](Map)) 311 v.EachObjxMap(func(index int, val Map) bool { 312 group := grouper(index, val) 313 if _, ok := groups[group]; !ok { 314 groups[group] = make([](Map), 0) 315 } 316 groups[group] = append(groups[group], val) 317 return true 318 }) 319 return &Value{data: groups} 320} 321 322// ReplaceObjxMap uses the specified function to replace each (Map)s 323// by iterating each item. The data in the returned result will be a 324// [](Map) containing the replaced items. 325func (v *Value) ReplaceObjxMap(replacer func(int, Map) Map) *Value { 326 arr := v.MustObjxMapSlice() 327 replaced := make([](Map), len(arr)) 328 v.EachObjxMap(func(index int, val Map) bool { 329 replaced[index] = replacer(index, val) 330 return true 331 }) 332 return &Value{data: replaced} 333} 334 335// CollectObjxMap uses the specified collector function to collect a value 336// for each of the (Map)s in the slice. The data returned will be a 337// []interface{}. 338func (v *Value) CollectObjxMap(collector func(int, Map) interface{}) *Value { 339 arr := v.MustObjxMapSlice() 340 collected := make([]interface{}, len(arr)) 341 v.EachObjxMap(func(index int, val Map) bool { 342 collected[index] = collector(index, val) 343 return true 344 }) 345 return &Value{data: collected} 346} 347