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

如何用Groovy在JSON指定位置添加字段及处理批量递增

解决Groovy中JSON指定位置插入键值对及批量递增赋值问题

首先得明确一点:JSON规范里对象的键是无序的,但很多时候我们希望输出的JSON保持特定的可读性顺序,这就需要借助有序的Map实现来处理。

问题1:在指定位置("sell": true之后)插入"total": "1000"

你的代码用json.put()会把键值对加到Map末尾,因为默认JsonSlurper解析出来的是普通HashMap(无序)。要实现有序插入,我们需要用LinkedHashMap来维护键的顺序,步骤如下:

  1. 先修正原JSON的语法错误(末尾多余的逗号会导致解析失败)
  2. 解析时指定使用有序的LinkedHashMap
  3. 遍历目标对象的键值对,在遇到sell键之后插入total

示例代码:

import groovy.json.JsonSlurper
import groovy.json.JsonOutput
import java.util.LinkedHashMap

// 修正后的JSON(去掉末尾多余的逗号)
def desiredJson = '{"count": 4, "max": "12", "min": 0, "details": [{"goBus": {"first": 12800, "second": 11900, "third": 12800},"goAir": {"first": 12800, "second": 11900, "third": 12800}, "gotTrain": {"first": 12800, "second": 11900},"sell": true, "darn": 2,"rate": [{ "busRate": 11900, "flag": false, "percent": 0}]}]}'

// 解析为有序的LinkedHashMap
def jsonSlurper = new JsonSlurper(type: JsonSlurper.Type.LINKED_HASH_MAP)
def json = jsonSlurper.parseText(desiredJson)

// 处理details里的每个对象(这里先处理单个的情况)
json.details.each { detail ->
    def newDetail = new LinkedHashMap()
    detail.each { key, value ->
        newDetail.put(key, value)
        // 当遇到sell键时,插入total
        if (key == 'sell') {
            newDetail.put('total', '1000')
        }
    }
    // 替换原来的detail对象
    json.details.set(json.details.indexOf(detail), newDetail)
}

// 输出格式化后的JSON
log.info JsonOutput.prettyPrint(JsonOutput.toJson(json))

运行后输出的JSON中,total会紧跟在sell之后:

{
    "count": 4,
    "max": "12",
    "min": 0,
    "details": [
        {
            "goBus": {
                "first": 12800,
                "second": 11900,
                "third": 12800
            },
            "goAir": {
                "first": 12800,
                "second": 11900,
                "third": 12800
            },
            "gotTrain": {
                "first": 12800,
                "second": 11900
            },
            "sell": true,
            "total": "1000",
            "darn": 2,
            "rate": [
                {
                    "busRate": 11900,
                    "flag": false,
                    "percent": 0
                }
            ]
        }
    ]
}

问题2:处理多个重复JSON对象,为每个对象添加递增的total值

如果details数组里有多个对象,我们只需要在遍历的时候维护一个计数器,每次赋值后递增即可:

示例代码:

import groovy.json.JsonSlurper
import groovy.json.JsonOutput
import java.util.LinkedHashMap

// 包含多个detail对象的JSON
def desiredJson = '{"count": 4, "max": "12", "min": 0, "details": [{"goBus": {"first": 12800},"sell": true}, {"goBus": {"first": 13800},"sell": true}, {"goBus": {"first": 14800},"sell": true}]}'

def jsonSlurper = new JsonSlurper(type: JsonSlurper.Type.LINKED_HASH_MAP)
def json = jsonSlurper.parseText(desiredJson)

// 初始化计数器
def totalValue = 1000
json.details.each { detail ->
    def newDetail = new LinkedHashMap()
    detail.each { key, value ->
        newDetail.put(key, value)
        if (key == 'sell') {
            newDetail.put('total', String.valueOf(totalValue++))
        }
    }
    json.details.set(json.details.indexOf(detail), newDetail)
}

log.info JsonOutput.prettyPrint(JsonOutput.toJson(json))

输出结果中,每个detail的total会依次是1000、1001、1002:

{
    "count": 4,
    "max": "12",
    "min": 0,
    "details": [
        {
            "goBus": {
                "first": 12800
            },
            "sell": true,
            "total": "1000"
        },
        {
            "goBus": {
                "first": 13800
            },
            "sell": true,
            "total": "1001"
        },
        {
            "goBus": {
                "first": 14800
            },
            "sell": true,
            "total": "1002"
        }
    ]
}

关键说明

  • 必须使用LinkedHashMap来维护键的顺序,因为普通HashMap不保证顺序
  • 遍历原对象的键值对,在目标键之后插入新键值对,再替换原对象,才能实现指定位置的效果
  • 批量处理时通过计数器实现值的递增,灵活调整初始值和步长即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:47:47