123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
- //
- // This Source Code Form is subject to the terms of the MIT License.
- // If a copy of the MIT was not distributed with this file,
- // You can obtain one at https://github.com/gogf/gf.
- package gutil
- import (
- "reflect"
- "github.com/gogf/gf/v2/util/gconv"
- )
- // SliceCopy does a shallow copy of slice `data` for most commonly used slice type
- // []interface{}.
- func SliceCopy(slice []interface{}) []interface{} {
- newSlice := make([]interface{}, len(slice))
- copy(newSlice, slice)
- return newSlice
- }
- // SliceInsertBefore inserts the `values` to the front of `index` and returns a new slice.
- func SliceInsertBefore(slice []interface{}, index int, values ...interface{}) (newSlice []interface{}) {
- if index < 0 || index >= len(slice) {
- return slice
- }
- newSlice = make([]interface{}, len(slice)+len(values))
- copy(newSlice, slice[0:index])
- copy(newSlice[index:], values)
- copy(newSlice[index+len(values):], slice[index:])
- return
- }
- // SliceInsertAfter inserts the `values` to the back of `index` and returns a new slice.
- func SliceInsertAfter(slice []interface{}, index int, values ...interface{}) (newSlice []interface{}) {
- if index < 0 || index >= len(slice) {
- return slice
- }
- newSlice = make([]interface{}, len(slice)+len(values))
- copy(newSlice, slice[0:index+1])
- copy(newSlice[index+1:], values)
- copy(newSlice[index+1+len(values):], slice[index+1:])
- return
- }
- // SliceDelete deletes an element at `index` and returns the new slice.
- // It does nothing if the given `index` is invalid.
- func SliceDelete(slice []interface{}, index int) (newSlice []interface{}) {
- if index < 0 || index >= len(slice) {
- return slice
- }
- // Determine array boundaries when deleting to improve deletion efficiency.
- if index == 0 {
- return slice[1:]
- } else if index == len(slice)-1 {
- return slice[:index]
- }
- // If it is a non-boundary delete,
- // it will involve the creation of an array,
- // then the deletion is less efficient.
- return append(slice[:index], slice[index+1:]...)
- }
- // SliceToMap converts slice type variable `slice` to `map[string]interface{}`.
- // Note that if the length of `slice` is not an even number, it returns nil.
- // Eg:
- // ["K1", "v1", "K2", "v2"] => {"K1": "v1", "K2": "v2"}
- // ["K1", "v1", "K2"] => nil
- func SliceToMap(slice interface{}) map[string]interface{} {
- var (
- reflectValue = reflect.ValueOf(slice)
- reflectKind = reflectValue.Kind()
- )
- for reflectKind == reflect.Ptr {
- reflectValue = reflectValue.Elem()
- reflectKind = reflectValue.Kind()
- }
- switch reflectKind {
- case reflect.Slice, reflect.Array:
- length := reflectValue.Len()
- if length%2 != 0 {
- return nil
- }
- data := make(map[string]interface{})
- for i := 0; i < reflectValue.Len(); i += 2 {
- data[gconv.String(reflectValue.Index(i).Interface())] = reflectValue.Index(i + 1).Interface()
- }
- return data
- }
- return nil
- }
- // SliceToMapWithColumnAsKey converts slice type variable `slice` to `map[interface{}]interface{}`
- // The value of specified column use as the key for returned map.
- // Eg:
- // SliceToMapWithColumnAsKey([{"K1": "v1", "K2": 1}, {"K1": "v2", "K2": 2}], "K1") => {"v1": {"K1": "v1", "K2": 1}, "v2": {"K1": "v2", "K2": 2}}
- // SliceToMapWithColumnAsKey([{"K1": "v1", "K2": 1}, {"K1": "v2", "K2": 2}], "K2") => {1: {"K1": "v1", "K2": 1}, 2: {"K1": "v2", "K2": 2}}
- func SliceToMapWithColumnAsKey(slice interface{}, key interface{}) map[interface{}]interface{} {
- var (
- reflectValue = reflect.ValueOf(slice)
- reflectKind = reflectValue.Kind()
- )
- for reflectKind == reflect.Ptr {
- reflectValue = reflectValue.Elem()
- reflectKind = reflectValue.Kind()
- }
- data := make(map[interface{}]interface{})
- switch reflectKind {
- case reflect.Slice, reflect.Array:
- for i := 0; i < reflectValue.Len(); i++ {
- if k, ok := ItemValue(reflectValue.Index(i), key); ok {
- data[k] = reflectValue.Index(i).Interface()
- }
- }
- }
- return data
- }
|