github.com/zhongdalu/gf@v1.0.0/g/util/gconv/gconv_slice.go (about) 1 // Copyright 2017 gf Author(https://github.com/zhongdalu/gf). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/zhongdalu/gf. 6 7 package gconv 8 9 import ( 10 "errors" 11 "fmt" 12 "reflect" 13 14 "github.com/zhongdalu/gf/g/internal/strutils" 15 ) 16 17 // SliceInt is alias of Ints. 18 func SliceInt(i interface{}) []int { 19 return Ints(i) 20 } 21 22 // SliceStr is alias of Strings. 23 func SliceStr(i interface{}) []string { 24 return Strings(i) 25 } 26 27 // SliceAny is alias of Interfaces. 28 func SliceAny(i interface{}) []interface{} { 29 return Interfaces(i) 30 } 31 32 // SliceFloat is alias of Floats. 33 func SliceFloat(i interface{}) []float64 { 34 return Floats(i) 35 } 36 37 // SliceMap is alias of Maps. 38 func SliceMap(i interface{}) []map[string]interface{} { 39 return Maps(i) 40 } 41 42 // SliceMapDeep is alias of MapsDeep. 43 func SliceMapDeep(i interface{}) []map[string]interface{} { 44 return MapsDeep(i) 45 } 46 47 // SliceStruct is alias of Structs. 48 func SliceStruct(params interface{}, pointer interface{}, mapping ...map[string]string) (err error) { 49 return Structs(params, pointer, mapping...) 50 } 51 52 // SliceStructDeep is alias of StructsDeep. 53 func SliceStructDeep(params interface{}, pointer interface{}, mapping ...map[string]string) (err error) { 54 return StructsDeep(params, pointer, mapping...) 55 } 56 57 // Ints converts <i> to []int. 58 func Ints(i interface{}) []int { 59 if i == nil { 60 return nil 61 } 62 if r, ok := i.([]int); ok { 63 return r 64 } else { 65 array := make([]int, 0) 66 switch value := i.(type) { 67 case []string: 68 for _, v := range value { 69 array = append(array, Int(v)) 70 } 71 case []int8: 72 for _, v := range value { 73 array = append(array, Int(v)) 74 } 75 case []int16: 76 for _, v := range value { 77 array = append(array, Int(v)) 78 } 79 case []int32: 80 for _, v := range value { 81 array = append(array, Int(v)) 82 } 83 case []int64: 84 for _, v := range value { 85 array = append(array, Int(v)) 86 } 87 case []uint: 88 for _, v := range value { 89 array = append(array, Int(v)) 90 } 91 case []uint8: 92 for _, v := range value { 93 array = append(array, Int(v)) 94 } 95 case []uint16: 96 for _, v := range value { 97 array = append(array, Int(v)) 98 } 99 case []uint32: 100 for _, v := range value { 101 array = append(array, Int(v)) 102 } 103 case []uint64: 104 for _, v := range value { 105 array = append(array, Int(v)) 106 } 107 case []bool: 108 for _, v := range value { 109 array = append(array, Int(v)) 110 } 111 case []float32: 112 for _, v := range value { 113 array = append(array, Int(v)) 114 } 115 case []float64: 116 for _, v := range value { 117 array = append(array, Int(v)) 118 } 119 case []interface{}: 120 for _, v := range value { 121 array = append(array, Int(v)) 122 } 123 case [][]byte: 124 for _, v := range value { 125 array = append(array, Int(v)) 126 } 127 default: 128 return []int{Int(i)} 129 } 130 return array 131 } 132 } 133 134 // Strings converts <i> to []string. 135 func Strings(i interface{}) []string { 136 if i == nil { 137 return nil 138 } 139 if r, ok := i.([]string); ok { 140 return r 141 } else { 142 array := make([]string, 0) 143 switch value := i.(type) { 144 case []int: 145 for _, v := range value { 146 array = append(array, String(v)) 147 } 148 case []int8: 149 for _, v := range value { 150 array = append(array, String(v)) 151 } 152 case []int16: 153 for _, v := range value { 154 array = append(array, String(v)) 155 } 156 case []int32: 157 for _, v := range value { 158 array = append(array, String(v)) 159 } 160 case []int64: 161 for _, v := range value { 162 array = append(array, String(v)) 163 } 164 case []uint: 165 for _, v := range value { 166 array = append(array, String(v)) 167 } 168 case []uint8: 169 for _, v := range value { 170 array = append(array, String(v)) 171 } 172 case []uint16: 173 for _, v := range value { 174 array = append(array, String(v)) 175 } 176 case []uint32: 177 for _, v := range value { 178 array = append(array, String(v)) 179 } 180 case []uint64: 181 for _, v := range value { 182 array = append(array, String(v)) 183 } 184 case []bool: 185 for _, v := range value { 186 array = append(array, String(v)) 187 } 188 case []float32: 189 for _, v := range value { 190 array = append(array, String(v)) 191 } 192 case []float64: 193 for _, v := range value { 194 array = append(array, String(v)) 195 } 196 case []interface{}: 197 for _, v := range value { 198 array = append(array, String(v)) 199 } 200 case [][]byte: 201 for _, v := range value { 202 array = append(array, String(v)) 203 } 204 default: 205 return []string{String(i)} 206 } 207 return array 208 } 209 } 210 211 // Strings converts <i> to []float64. 212 func Floats(i interface{}) []float64 { 213 if i == nil { 214 return nil 215 } 216 if r, ok := i.([]float64); ok { 217 return r 218 } else { 219 array := make([]float64, 0) 220 switch value := i.(type) { 221 case []string: 222 for _, v := range value { 223 array = append(array, Float64(v)) 224 } 225 case []int: 226 for _, v := range value { 227 array = append(array, Float64(v)) 228 } 229 case []int8: 230 for _, v := range value { 231 array = append(array, Float64(v)) 232 } 233 case []int16: 234 for _, v := range value { 235 array = append(array, Float64(v)) 236 } 237 case []int32: 238 for _, v := range value { 239 array = append(array, Float64(v)) 240 } 241 case []int64: 242 for _, v := range value { 243 array = append(array, Float64(v)) 244 } 245 case []uint: 246 for _, v := range value { 247 array = append(array, Float64(v)) 248 } 249 case []uint8: 250 for _, v := range value { 251 array = append(array, Float64(v)) 252 } 253 case []uint16: 254 for _, v := range value { 255 array = append(array, Float64(v)) 256 } 257 case []uint32: 258 for _, v := range value { 259 array = append(array, Float64(v)) 260 } 261 case []uint64: 262 for _, v := range value { 263 array = append(array, Float64(v)) 264 } 265 case []bool: 266 for _, v := range value { 267 array = append(array, Float64(v)) 268 } 269 case []float32: 270 for _, v := range value { 271 array = append(array, Float64(v)) 272 } 273 case []interface{}: 274 for _, v := range value { 275 array = append(array, Float64(v)) 276 } 277 default: 278 return []float64{Float64(i)} 279 } 280 return array 281 } 282 } 283 284 // Interfaces converts <i> to []interface{}. 285 func Interfaces(i interface{}) []interface{} { 286 if i == nil { 287 return nil 288 } 289 if r, ok := i.([]interface{}); ok { 290 return r 291 } else { 292 array := make([]interface{}, 0) 293 switch value := i.(type) { 294 case []string: 295 for _, v := range value { 296 array = append(array, v) 297 } 298 case []int: 299 for _, v := range value { 300 array = append(array, v) 301 } 302 case []int8: 303 for _, v := range value { 304 array = append(array, v) 305 } 306 case []int16: 307 for _, v := range value { 308 array = append(array, v) 309 } 310 case []int32: 311 for _, v := range value { 312 array = append(array, v) 313 } 314 case []int64: 315 for _, v := range value { 316 array = append(array, v) 317 } 318 case []uint: 319 for _, v := range value { 320 array = append(array, v) 321 } 322 case []uint8: 323 for _, v := range value { 324 array = append(array, v) 325 } 326 case []uint16: 327 for _, v := range value { 328 array = append(array, v) 329 } 330 case []uint32: 331 for _, v := range value { 332 array = append(array, v) 333 } 334 case []uint64: 335 for _, v := range value { 336 array = append(array, v) 337 } 338 case []bool: 339 for _, v := range value { 340 array = append(array, v) 341 } 342 case []float32: 343 for _, v := range value { 344 array = append(array, v) 345 } 346 case []float64: 347 for _, v := range value { 348 array = append(array, v) 349 } 350 default: 351 // Finally we use reflection. 352 rv := reflect.ValueOf(i) 353 kind := rv.Kind() 354 // If it's pointer, find the real type. 355 if kind == reflect.Ptr { 356 rv = rv.Elem() 357 kind = rv.Kind() 358 } 359 switch kind { 360 case reflect.Slice, reflect.Array: 361 for i := 0; i < rv.Len(); i++ { 362 array = append(array, rv.Index(i).Interface()) 363 } 364 case reflect.Struct: 365 rt := rv.Type() 366 for i := 0; i < rv.NumField(); i++ { 367 // Only public attributes. 368 if !strutils.IsLetterUpper(rt.Field(i).Name[0]) { 369 continue 370 } 371 array = append(array, rv.Field(i).Interface()) 372 } 373 default: 374 return []interface{}{i} 375 } 376 } 377 return array 378 } 379 } 380 381 // Maps converts <i> to []map[string]interface{}. 382 func Maps(value interface{}, tags ...string) []map[string]interface{} { 383 if value == nil { 384 return nil 385 } 386 if r, ok := value.([]map[string]interface{}); ok { 387 return r 388 } else { 389 array := Interfaces(value) 390 if len(array) == 0 { 391 return nil 392 } 393 list := make([]map[string]interface{}, len(array)) 394 for k, v := range array { 395 list[k] = Map(v, tags...) 396 } 397 return list 398 } 399 } 400 401 // MapsDeep converts <i> to []map[string]interface{} recursively. 402 func MapsDeep(value interface{}, tags ...string) []map[string]interface{} { 403 if value == nil { 404 return nil 405 } 406 if r, ok := value.([]map[string]interface{}); ok { 407 return r 408 } else { 409 array := Interfaces(value) 410 if len(array) == 0 { 411 return nil 412 } 413 list := make([]map[string]interface{}, len(array)) 414 for k, v := range array { 415 list[k] = MapDeep(v, tags...) 416 } 417 return list 418 } 419 } 420 421 // Structs converts any slice to given struct slice. 422 func Structs(params interface{}, pointer interface{}, mapping ...map[string]string) (err error) { 423 return doStructs(params, pointer, false, mapping...) 424 } 425 426 // StructsDeep converts any slice to given struct slice recursively. 427 func StructsDeep(params interface{}, pointer interface{}, mapping ...map[string]string) (err error) { 428 return doStructs(params, pointer, true, mapping...) 429 } 430 431 // doStructs converts any slice to given struct slice. 432 // 433 // The parameter <params> should be type of slice. 434 // 435 // The parameter <pointer> should be type of pointer to slice of struct. 436 // Note that if <pointer> is a pointer to another pointer of type of slice of struct, 437 // it will create the struct/pointer internally. 438 func doStructs(params interface{}, pointer interface{}, deep bool, mapping ...map[string]string) (err error) { 439 if params == nil { 440 return errors.New("params cannot be nil") 441 } 442 if pointer == nil { 443 return errors.New("object pointer cannot be nil") 444 } 445 pointerRt := reflect.TypeOf(pointer) 446 if kind := pointerRt.Kind(); kind != reflect.Ptr { 447 return fmt.Errorf("pointer should be type of pointer, but got: %v", kind) 448 } 449 450 rv := reflect.ValueOf(params) 451 kind := rv.Kind() 452 if kind == reflect.Ptr { 453 rv = rv.Elem() 454 kind = rv.Kind() 455 } 456 switch kind { 457 case reflect.Slice, reflect.Array: 458 // If <params> is an empty slice, no conversion. 459 if rv.Len() == 0 { 460 return nil 461 } 462 array := reflect.MakeSlice(pointerRt.Elem(), rv.Len(), rv.Len()) 463 itemType := array.Index(0).Type() 464 for i := 0; i < rv.Len(); i++ { 465 if itemType.Kind() == reflect.Ptr { 466 // Slice element is type pointer. 467 e := reflect.New(itemType.Elem()).Elem() 468 if deep { 469 if err = StructDeep(rv.Index(i).Interface(), e, mapping...); err != nil { 470 return err 471 } 472 } else { 473 if err = Struct(rv.Index(i).Interface(), e, mapping...); err != nil { 474 return err 475 } 476 } 477 array.Index(i).Set(e.Addr()) 478 } else { 479 // Slice element is not type of pointer. 480 e := reflect.New(itemType).Elem() 481 482 if deep { 483 if err = StructDeep(rv.Index(i).Interface(), e, mapping...); err != nil { 484 return err 485 } 486 } else { 487 if err = Struct(rv.Index(i).Interface(), e, mapping...); err != nil { 488 return err 489 } 490 } 491 array.Index(i).Set(e) 492 } 493 } 494 reflect.ValueOf(pointer).Elem().Set(array) 495 return nil 496 default: 497 return fmt.Errorf("params should be type of slice, but got: %v", kind) 498 } 499 }