我正在使用 Go 中的两个 map[string]interface{} 类型的对象,我需要创建一个函数来返回这些对象之间的所有差异。我知道 reflect.DeepEqual(m1, m2) 可以告诉...
我正在使用 Go 中的两个 map[string]interface{} 类型的对象,我需要创建一个函数来返回这些对象之间的所有差异。我知道 reflect.DeepEqual(m1, m2) 可以告诉我它们是否相等,但我需要知道哪些字段已更改。
我希望该函数返回如下结构:
{
"id": {
"before": "example",
"now": "example2"
},
"name": {
"before": "oldName",
"now": "newName"
}
// other fields...
}
以下是函数签名的示例:
func FindDifferences(m1, m2 map\[string\]interface{}) map\[string\]map\[string\]interface{} {
// implementation
}
我尝试实现此功能,但遇到了问题。以下是实现和失败的测试用例:
func FindDifferences(m1, m2 map[string]interface{}) map[string]map[string]interface{} {
differences := make(map[string]map[string]interface{})
for k, v1 := range m1 {
if v2, ok := m2[k]; ok {
if !reflect.DeepEqual(v1, v2) {
differences[k] = map[string]interface{}{
"before": v1,
"now": v2,
}
}
} else {
differences[k] = map[string]interface{}{
"before": v1,
"now": nil,
}
}
}
for k, v2 := range m2 {
if _, ok := m1[k]; !ok {
differences[k] = map[string]interface{}{
"before": nil,
"now": v2,
}
}
}
return differences
}
测试:
func TestFindDifferences(t *testing.T) {
m1 := map[string]interface{}{
"id": "d7f3c1e8-6b5a-4c9a-b28d-1b6345f28978",
"name": "Greenhouse-Management-System",
"garden_id": "a2b9c8f3-45d1-4e2d-bc1e-7845f3c91b27",
"garden_version": "1.0",
"enabled": true,
"template": false,
"nodes": []interface{}{
map[string]interface{}{
"id": "3f5a6d8e-8235-4d1a-8f37-e5c9f1a5c7b3",
"name": "Tomato-Section",
"desc": "Section for growing tomatoes",
"type": "plant:solanaceae",
"value": map[string]interface{}{
"soil_ph": 6.5,
"watering_schedule": "daily",
"fertilizer": "compost",
"max_height": 2.0,
"max_width": 1.5,
"harvest_time": "60 days",
},
"mode": "crop",
"parents": []interface{}{
"1a2b3c4d-5e6f-7g8h-9i0j-1k2l3m4n5o6p",
},
"children": []interface{}{},
},
map[string]interface{}{
"id": "1a2b3c4d-5e6f-7g8h-9i0j-1k2l3m4n5o6p",
"name": "Irrigation-System",
"desc": "Automated irrigation system",
"type": "infrastructure:water",
"value": map[string]interface{}{
"water_source": "rainwater_tank",
"flow_rate": "10 liters/minute",
},
"mode": "support",
"parents": []interface{}{},
"children": []interface{}{
"3f5a6d8e-8235-4d1a-8f37-e5c9f1a5c7b3",
},
},
},
}
m2 := map[string]interface{}{
"id": "d7f3c1e8-6b5a-4c9a-b28d-1b6345f28978",
"name": "Greenhouse-Management-System",
"garden_id": "a2b9c8f3-45d1-4e2d-bc1e-7845f3c91b27",
"garden_version": "1.0",
"enabled": true,
"template": false,
"nodes": []interface{}{
map[string]interface{}{
"id": "3f5a6d8e-8235-4d1a-8f37-e5c9f1a5c7b3",
"name": "Tomato-Section",
"desc": "Section for growing tomatoes",
"type": "plant:fyvgukhl",
"value": map[string]interface{}{
"soil_ph": 6.5,
"watering_schedule": "daily",
"fertilizer": "compost",
"max_height": 2.0,
"max_width": 1.5,
"harvest_time": "60 days",
},
"mode": "crop",
"parents": []interface{}{
"1a2b3c4d-5e6f-7g8h-9i0j-1k2l3m4n5o6p",
},
"children": []interface{}{},
},
map[string]interface{}{
"id": "1a2b3c4d-5e6f-7g8h-9i0j-1k2l3m4n5o6p",
"name": "Irrigation-System",
"desc": "Automated irrigation system",
"type": "infrastructure:water",
"value": map[string]interface{}{
"water_source": "rainwater_tank",
"flow_rate": "10 liters/minute",
},
"mode": "support",
"parents": []interface{}{},
"children": []interface{}{
"3f5a6d8e-8235-4d1a-8f37-e5c9f1a5c7b3",
},
},
},
}
expected := map[string]map[string]interface{}{
"id": {
"before": "example",
"now": "example2",
},
"name": {
"before": "oldName",
"now": "newName",
},
}
result := FindDifferences(m1, m2)
if !reflect.DeepEqual(result, expected) {
t.Errorf("Expected %v, but got %v", expected, result)
}
}
测试用例失败,输出以下信息:
Expected map[string][]map[string]map[string]string{
"nodes": {
{
"type": {
"before": "plant:solanaceae",
"now": "plant:fyvgukhl",
},
},
},
}
看起来该函数错误地将未更改的字段包含在结果中。我该如何修改该函数以正确识别并仅列出已更改的字段?
该代码适用于 1 层对象,但我想要一个适用于 3 层的代码。