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