如何用标准库优化字符串列表转分组映射的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()
优化说明
- 合并了多次
collect操作,用命名的key/value映射替代匿名列表,提升代码可读性 - 简化正则表达式:不再限制中间必须是3个单词,用
.+匹配任意中间内容,适配更多场景 - 使用
entries*.value简化值列表的提取,替代嵌套的collect - 直接用
findAll筛选目标行,替代groupBy后取partitioned[true],逻辑更直观 - 全程使用Groovy标准库方法,避免类型不匹配问题
内容的提问来源于stack exchange,提问作者java-coding-prodigy
相关产品推荐
相关产品推荐

