feat: 深度克隆支持map复制
This commit is contained in:
@ -9,6 +9,7 @@ package op_array
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// ToMap 数组转map
|
||||
@ -112,3 +113,34 @@ func Tree[ID comparable, Value any](dataList []Value, formatParentID func(v Valu
|
||||
}
|
||||
return rootData
|
||||
}
|
||||
|
||||
// DeepClone 深度克隆一个数组, 每一个元素的地址均重新分配
|
||||
func DeepClone[Value any](dataList []Value) []Value {
|
||||
v := *new(Value)
|
||||
vType := reflect.TypeOf(v)
|
||||
res := make([]Value, len(dataList))
|
||||
for i := 0; i < len(dataList); i++ {
|
||||
newV := new(Value)
|
||||
switch vType.Kind() {
|
||||
case reflect.Ptr:
|
||||
// 解引用, 并单独读取值后重新分配地址
|
||||
copyV := reflect.New(vType.Elem()).Elem()
|
||||
copyV.Set(reflect.ValueOf(dataList[i]).Elem())
|
||||
*newV = copyV.Addr().Interface().(Value)
|
||||
case reflect.Map:
|
||||
mapVal := reflect.ValueOf(dataList[i])
|
||||
mapKeyList := mapVal.MapKeys()
|
||||
newMap := reflect.MakeMap(vType)
|
||||
for _, key := range mapKeyList {
|
||||
// 通过键获取对应的值
|
||||
value := mapVal.MapIndex(key)
|
||||
newMap.SetMapIndex(key, value)
|
||||
}
|
||||
*newV = newMap.Interface().(Value)
|
||||
default:
|
||||
*newV = dataList[i]
|
||||
}
|
||||
res[i] = *newV
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
package op_array
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"git.zhangdeman.cn/zhangdeman/serialize"
|
||||
@ -32,3 +33,38 @@ func TestTree(t *testing.T) {
|
||||
res := Tree(dataList, func(v Data) int { return v.ParentID }, func(v Data) int { return v.ID })
|
||||
serialize.JSON.ConsoleOutput(res)
|
||||
}
|
||||
|
||||
func TestClone(t *testing.T) {
|
||||
type Data struct {
|
||||
ID int `json:"id" dc:"数据ID"`
|
||||
}
|
||||
|
||||
// 字面结构体
|
||||
dataList := []Data{
|
||||
{ID: 1},
|
||||
{ID: 2},
|
||||
}
|
||||
res := DeepClone(dataList)
|
||||
fmt.Println(fmt.Sprintf("%p", &res[0]), fmt.Sprintf("%p", &dataList[0]))
|
||||
fmt.Println(fmt.Sprintf("%p", &res[1]), fmt.Sprintf("%p", &dataList[1]))
|
||||
|
||||
// 结构体指针
|
||||
dataList1 := []*Data{
|
||||
{ID: 1},
|
||||
{ID: 2},
|
||||
}
|
||||
res1 := DeepClone(dataList1)
|
||||
fmt.Println(fmt.Sprintf("%p", &res1[0]), fmt.Sprintf("%p", &dataList1[0]))
|
||||
fmt.Println(fmt.Sprintf("%p", &res1[1]), fmt.Sprintf("%p", &dataList1[1]))
|
||||
|
||||
// Map数据
|
||||
dataList2 := []map[string]any{
|
||||
{"id": 1},
|
||||
{"id": 2},
|
||||
}
|
||||
res2 := DeepClone(dataList2)
|
||||
fmt.Println(fmt.Sprintf("%p", &res2[0]), fmt.Sprintf("%p", &dataList2[0]))
|
||||
fmt.Println(fmt.Sprintf("%p", &res2[1]), fmt.Sprintf("%p", &dataList2[1]))
|
||||
serialize.JSON.ConsoleOutput(res2)
|
||||
serialize.JSON.ConsoleOutput(dataList2)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user