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

Groovy实现同coverageType数组元素分组到父元素子列表的方法

Groovy 数组分组结构化处理问题

我有一个数组列表,尝试用Groovy做结构化处理但没得到预期结果,使用putAll添加数组时会覆盖之前的数据,我的代码如下:

import java.util.stream.Collectors

def fakeList = [
        [coverageType: 'health', amount: 9, expireDate: 2020], 
        [coverageType: 'insurance', amount: 10, expireDate: 2020], 
        [coverageType: 'health', amount: 9, expireDate: 2021],
] 

def groupList = [:]
def list = fakeList
        .stream()
        .map { item -> 
                def parentWithChilds = [
                        parent: item.coverageType,
                        child: groupList.stream()
                        .map { list -> list?.parent !== item.coverageType }
                        .collect(Collectors.toList())
                    ]
                    groupList.putAll(parentWithChilds)
        }.collect(java.util.stream.Collectors.toList())

得到的输出是[parent:health, children:[true]],完全不符合预期。我需要把所有coverageType相同的元素归到对应父元素的子列表里,预期两种输出格式:

预期格式一:带键的子元素

[    
    [
        parent: 'health',
        children: [
            [
                coverageType: 'health',
                amount:'9',
                expireDate: '2020'                        
            ],
            [
                coverageType: 'health',
                amount:'9',
                expireDate: '2021'                        
            ],
        ]
    ],
    [
        parent: 'insurance',
        children: [
            [
                coverageType: 'insurance',
                amount: '10',
                expireDate: '2020'                        
            ]
        ]
    ]
]

预期格式二:无键的子元素(仅保留值)

[    
    [
        parent: 'health',
        children: [
            ['health', '9', '2020'],
            ['health', '9', '2021']
        ]
    ],
    [
        parent: 'insurance',
        children: [
            ['insurance', '10', '2020']
        ]
    ]
]

解决方案

原代码逻辑混乱,没必要用Java Stream的复杂写法,Groovy原生的groupBy方法就能高效实现分组,再转换为目标结构即可。

实现格式一(带键子元素)

def fakeList = [
        [coverageType: 'health', amount: 9, expireDate: 2020], 
        [coverageType: 'insurance', amount: 10, expireDate: 2020], 
        [coverageType: 'health', amount: 9, expireDate: 2021],
]

// 按coverageType分组后转换为目标结构
def resultWithKeys = fakeList.groupBy { it.coverageType }.collect { type, items ->
    [
        parent: type,
        children: items // 直接保留原元素的键值对列表
    ]
}

println resultWithKeys

实现格式二(无键子元素)

def fakeList = [
        [coverageType: 'health', amount: 9, expireDate: 2020], 
        [coverageType: 'insurance', amount: 10, expireDate: 2020], 
        [coverageType: 'health', amount: 9, expireDate: 2021],
]

def resultWithoutKeys = fakeList.groupBy { it.coverageType }.collect { type, items ->
    [
        parent: type,
        children: items.collect { item ->
            // 按顺序提取元素的值组成无键列表
            [item.coverageType, item.amount.toString(), item.expireDate.toString()]
        }
    ]
}

println resultWithoutKeys

代码说明

  1. groupBy { it.coverageType }:快速按coverageType分组,得到键为类型名、值为对应元素列表的Map。
  2. collect转换结构:遍历分组后的Map,将每个键值对映射为parent+children的结构。
  3. 格式二中的toString()用于将数字类型的amount和expireDate转为字符串,匹配预期输出格式;若不需要字符串类型,可直接去掉。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 05:50:24