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

如何用标准库优化字符串列表转分组映射的Groovy实现?

Groovy优化实现:提取整数并按键分组

需求:从字符串中提取两个整数,以第二个整数为键、第一个为值,按键进行分组。现有一段Groovy实现,希望找到基于标准库方法的更优实现方案,此前尝试subMap和collectEntries时遇到类型问题无法解决。

输入示例

Vyz 15 blah blah blah 23
VBC 25 Foo bar Baz 37
Vqr 17 brr brr brr 23

期望输出

[23:[15,17], 37:[25]]

当前实现代码

def partitioned = input.groupBy{it[0] =='v'}
def groupedResult = partitioned[true].collect { (it =~ /\w+ (\d+) (?:\w+ ){3}(\d+)/)[0] }.collect { [it[2].toInteger(), it[1].toInteger()] }.groupBy { it[0] }.collectEntries { k, v -> [k, v.collect { it[1] }] }.withDefault { new ArrayList<Integer>() }
def left = partitioned[false].toSet()

优化实现方案

可以通过简化中间步骤、增强代码可读性的方式,用Groovy标准库方法实现更简洁的逻辑:

// 筛选以v开头的行,提取键值对后分组
def groupedResult = input.findAll { it[0] == 'v' }
    .collect { line ->
        // 匹配行中的两个整数,正则简化为匹配任意中间内容
        def match = (line =~ /\w+ (\d+) .+ (\d+)/)[0]
        [key: match[2].toInteger(), value: match[1].toInteger()]
    }
    .groupBy { it.key }
    // 将分组后的value列表提取出来
    .collectEntries { k, entries -> [k, entries*.value] }
    // 设置默认空列表
    .withDefault { [] }

// 处理非v开头的行
def left = input.findAll { it[0] != 'v' }.toSet()

优化说明

  1. 合并了多次collect操作,用命名的key/value映射替代匿名列表,提升代码可读性
  2. 简化正则表达式:不再限制中间必须是3个单词,用.+匹配任意中间内容,适配更多场景
  3. 使用entries*.value简化值列表的提取,替代嵌套的collect
  4. 直接用findAll筛选目标行,替代groupBy后取partitioned[true],逻辑更直观
  5. 全程使用Groovy标准库方法,避免类型不匹配问题

内容的提问来源于stack exchange,提问作者java-coding-prodigy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 17:05:04