diff --git a/util/gutil/gutil_slice.go b/util/gutil/gutil_slice.go index c2a183495..7da40a8db 100644 --- a/util/gutil/gutil_slice.go +++ b/util/gutil/gutil_slice.go @@ -65,3 +65,29 @@ func SliceToMap(slice interface{}) map[string]interface{} { } 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 +} diff --git a/util/gutil/gutil_z_unit_slice_test.go b/util/gutil/gutil_z_unit_slice_test.go index 0f3f61938..218b1b65b 100755 --- a/util/gutil/gutil_z_unit_slice_test.go +++ b/util/gutil/gutil_z_unit_slice_test.go @@ -35,3 +35,23 @@ func Test_SliceToMap(t *testing.T) { t.Assert(m, nil) }) } + +func Test_SliceToMapWithColumnAsKey(t *testing.T) { + m1 := g.Map{"K1": "v1", "K2": 1} + m2 := g.Map{"K1": "v2", "K2": 2} + s := g.Slice{m1, m2} + gtest.C(t, func(t *gtest.T) { + m := gutil.SliceToMapWithColumnAsKey(s, "K1") + t.Assert(m, g.MapAnyAny{ + "v1": m1, + "v2": m2, + }) + }) + gtest.C(t, func(t *gtest.T) { + m := gutil.SliceToMapWithColumnAsKey(s, "K2") + t.Assert(m, g.MapAnyAny{ + 1: m1, + 2: m2, + }) + }) +}