add gutil.SliceToMap

This commit is contained in:
jflyfox
2020-12-25 15:34:54 +08:00
parent 306c02bcd4
commit 4e79b90863
2 changed files with 72 additions and 1 deletions

View File

@ -1,4 +1,4 @@
// Copyright 2017 gf Author(https://github.com/gogf/gf). All Rights Reserved.
// Copyright GoFrame Author(https://github.com/gogf/gf). 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,
@ -6,6 +6,11 @@
package gutil
import (
"github.com/gogf/gf/util/gconv"
"reflect"
)
// SliceCopy does a shallow copy of slice <data> for most commonly used slice type
// []interface{}.
func SliceCopy(data []interface{}) []interface{} {
@ -31,3 +36,32 @@ func SliceDelete(data []interface{}, index int) (newSlice []interface{}) {
// then the deletion is less efficient.
return append(data[:index], data[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
}

View File

@ -0,0 +1,37 @@
// Copyright GoFrame Author(https://github.com/gogf/gf). 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_test
import (
"github.com/gogf/gf/frame/g"
"testing"
"github.com/gogf/gf/test/gtest"
"github.com/gogf/gf/util/gutil"
)
func Test_SliceToMap(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
s := g.Slice{
"K1", "v1", "K2", "v2",
}
m := gutil.SliceToMap(s)
t.Assert(len(m), 2)
t.Assert(m, g.Map{
"K1": "v1",
"K2": "v2",
})
})
gtest.C(t, func(t *gtest.T) {
s := g.Slice{
"K1", "v1", "K2",
}
m := gutil.SliceToMap(s)
t.Assert(len(m), 0)
t.Assert(m, nil)
})
}