diff --git a/util/gutil/gutil_slice.go b/util/gutil/gutil_slice.go index b02106131..81161f6ce 100644 --- a/util/gutil/gutil_slice.go +++ b/util/gutil/gutil_slice.go @@ -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 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 +} diff --git a/util/gutil/gutil_z_unit_slice_test.go b/util/gutil/gutil_z_unit_slice_test.go new file mode 100755 index 000000000..768e504a9 --- /dev/null +++ b/util/gutil/gutil_z_unit_slice_test.go @@ -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) + }) +}