You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Golang合并含相同uid的相似数据切片并生成JSON

嘿,这个场景在Go里处理起来其实挺清晰的,核心思路就是利用uid作为唯一标识,先把两个切片的数据聚合到一个map里做字段合并,再转回切片序列化就行。我给你一步步拆解:

步骤1:解析两个端点的响应到结构体切片

首先,既然两个端点都基于同一个Item结构体返回JSON,那我们可以直接用json.Unmarshal把它们的响应字节解析成[]Item类型:

// 先定义你的结构体(按你提供的补充完整)
type NestedVal struct {
    // 这里根据你的实际嵌套字段定义,比如:
    ID string `json:"id"`
}

type Item struct {
    Uid  string     `json:"uid"`
    Val1 string     `json:"param1,omitempty"`
    Val2 []NestedVal `json:"param2,omitempty"`
    Val5 int        `json:"param5,omitempty"`
    Val6 string     `json:"param6,omitempty"`
}

// 假设resp1是第一个端点返回的JSON字节,resp2是第二个端点的
var items1, items2 []Item

// 解析第一个响应
if err := json.Unmarshal(resp1, &items1); err != nil {
    log.Fatalf("解析第一个端点响应失败: %v", err)
}

// 解析第二个响应
if err := json.Unmarshal(resp2, &items2); err != nil {
    log.Fatalf("解析第二个端点响应失败: %v", err)
}
步骤2:用Map按UID合并数据

因为uid是唯一共同属性,我们可以创建一个map[string]Item,键是uid,值是合并后的Item。遍历两个切片,把非空的字段合并到对应的条目里:

// 初始化map存储合并后的Item
itemMap := make(map[string]Item)

// 先把第一个切片的所有元素存入map
for _, item := range items1 {
    itemMap[item.Uid] = item
}

// 遍历第二个切片,合并字段到已有条目(或新增条目)
for _, item := range items2 {
    existingItem, exists := itemMap[item.Uid]
    if !exists {
        // 如果这个uid在map里不存在,直接添加
        itemMap[item.Uid] = item
        continue
    }

    // 开始合并字段:只覆盖/补充非空的字段
    if item.Val1 != "" {
        existingItem.Val1 = item.Val1
    }
    // 对于切片类型Val2:把新的元素追加到原有切片后面
    existingItem.Val2 = append(existingItem.Val2, item.Val2...)
    // 注意:如果Val5业务上允许0作为有效值,这里的判断要调整(比如改成指针类型)
    if item.Val5 != 0 {
        existingItem.Val5 = item.Val5
    }
    if item.Val6 != "" {
        existingItem.Val6 = item.Val6
    }

    // 更新map里的合并后条目
    itemMap[item.Uid] = existingItem
}
步骤3:转切片并序列化为JSON

最后把map里的值转成切片,再用json.Marshal(或MarshalIndent美化输出)序列化成JSON:

// 把map的值转成切片
mergedItems := make([]Item, 0, len(itemMap))
for _, item := range itemMap {
    mergedItems = append(mergedItems, item)
}

// 序列化为JSON
mergedJSON, err := json.MarshalIndent(mergedItems, "", "  ")
if err != nil {
    log.Fatalf("序列化合并后数据失败: %v", err)
}

// 输出结果,或者返回给调用方
fmt.Println(string(mergedJSON))
关键注意事项
  • 字段合并规则:上面的逻辑是“用第二个切片的非空字段覆盖第一个的”,如果你的业务需要其他规则(比如保留第一个的非空字段、对冲突字段做特殊处理),直接修改合并字段的判断逻辑就行。
  • 值类型的零值问题:比如Val5是int类型,零值是0,如果你的业务场景中0是有效的值,那上面的item.Val5 != 0判断就会把有效的0当成“未设置”。这时候建议把Val5改成指针类型*int,这样就能通过nil来判断是否是未设置的状态。
  • 嵌套字段合并:如果NestedVal里还有需要合并的字段,你需要在合并Val2的时候,针对每个嵌套元素做更细粒度的合并逻辑。

内容的提问来源于stack exchange,提问作者user4468000

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:35:30