github.com/gogf/gf@v1.16.9/util/gutil/gutil_slice.go (about) 1 // Copyright GoFrame Author(https://goframe.org). 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/gogf/gf. 6 7 package gutil 8 9 import ( 10 "github.com/gogf/gf/util/gconv" 11 "reflect" 12 ) 13 14 // SliceCopy does a shallow copy of slice `data` for most commonly used slice type 15 // []interface{}. 16 func SliceCopy(data []interface{}) []interface{} { 17 newData := make([]interface{}, len(data)) 18 copy(newData, data) 19 return newData 20 } 21 22 // SliceDelete deletes an element at `index` and returns the new slice. 23 // It does nothing if the given `index` is invalid. 24 func SliceDelete(data []interface{}, index int) (newSlice []interface{}) { 25 if index < 0 || index >= len(data) { 26 return data 27 } 28 // Determine array boundaries when deleting to improve deletion efficiency. 29 if index == 0 { 30 return data[1:] 31 } else if index == len(data)-1 { 32 return data[:index] 33 } 34 // If it is a non-boundary delete, 35 // it will involve the creation of an array, 36 // then the deletion is less efficient. 37 return append(data[:index], data[index+1:]...) 38 } 39 40 // SliceToMap converts slice type variable `slice` to `map[string]interface{}`. 41 // Note that if the length of `slice` is not an even number, it returns nil. 42 // Eg: 43 // ["K1", "v1", "K2", "v2"] => {"K1": "v1", "K2": "v2"} 44 // ["K1", "v1", "K2"] => nil 45 func SliceToMap(slice interface{}) map[string]interface{} { 46 var ( 47 reflectValue = reflect.ValueOf(slice) 48 reflectKind = reflectValue.Kind() 49 ) 50 for reflectKind == reflect.Ptr { 51 reflectValue = reflectValue.Elem() 52 reflectKind = reflectValue.Kind() 53 } 54 switch reflectKind { 55 case reflect.Slice, reflect.Array: 56 length := reflectValue.Len() 57 if length%2 != 0 { 58 return nil 59 } 60 data := make(map[string]interface{}) 61 for i := 0; i < reflectValue.Len(); i += 2 { 62 data[gconv.String(reflectValue.Index(i).Interface())] = reflectValue.Index(i + 1).Interface() 63 } 64 return data 65 } 66 return nil 67 } 68 69 // SliceToMapWithColumnAsKey converts slice type variable `slice` to `map[interface{}]interface{}` 70 // The value of specified column use as the key for returned map. 71 // Eg: 72 // SliceToMapWithColumnAsKey([{"K1": "v1", "K2": 1}, {"K1": "v2", "K2": 2}], "K1") => {"v1": {"K1": "v1", "K2": 1}, "v2": {"K1": "v2", "K2": 2}} 73 // SliceToMapWithColumnAsKey([{"K1": "v1", "K2": 1}, {"K1": "v2", "K2": 2}], "K2") => {1: {"K1": "v1", "K2": 1}, 2: {"K1": "v2", "K2": 2}} 74 func SliceToMapWithColumnAsKey(slice interface{}, key interface{}) map[interface{}]interface{} { 75 var ( 76 reflectValue = reflect.ValueOf(slice) 77 reflectKind = reflectValue.Kind() 78 ) 79 for reflectKind == reflect.Ptr { 80 reflectValue = reflectValue.Elem() 81 reflectKind = reflectValue.Kind() 82 } 83 data := make(map[interface{}]interface{}) 84 switch reflectKind { 85 case reflect.Slice, reflect.Array: 86 for i := 0; i < reflectValue.Len(); i++ { 87 if k, ok := ItemValue(reflectValue.Index(i), key); ok { 88 data[k] = reflectValue.Index(i).Interface() 89 } 90 } 91 } 92 return data 93 }