Kotlin如何将CSV内容转换为Map<String, List<String>>结构
解决方案
你当前使用associate方法无法得到预期结果,是因为associate在遇到重复键时会直接用新值覆盖旧值,所以同一区域下的多个国家代码只会保留最后一个,你将值修改为listOf(code)也只会反复生成新的单元素列表覆盖已有值,自然无法得到多元素的列表。
最优实现方案
Kotlin标准库提供的groupBy方法完全适配这个需求,它有双参数重载,可以分别指定键的生成规则和值的转换规则,直接得到你要的Map<String, List<String>>结构,同时加入了空行过滤逻辑避免CSV首尾空行、中间空行导致的解析异常:
val result = csv.split("\n") .filter { it.isNotBlank() } .groupBy( keySelector = { line -> line.split(";")[1] }, valueTransform = { line -> line.split(";")[0] } )
你也可以调整写法让逻辑更清晰:
val result = csv.split("\n") .filterNot { it.isEmpty() } .map { it.split(";") } .groupBy({ (_, region) -> region }, { (code, _) -> code })
以上代码执行后得到的result就完全符合你给出的示例结构,区域为键、对应国家代码组成的列表为值。
可选实现(associate类API实现)
如果你一定要用associate相关的API实现,也可以借助可变集合完成,不过可读性和效率都不如直接使用groupBy:
val result = mutableMapOf<String, MutableList<String>>().also { map -> csv.split("\n") .filter { it.isNotBlank() } .map { it.split(";") } .forEach { (code, region) -> map.getOrPut(region) { mutableListOf() }.add(code) } }
内容的提问来源于stack exchange,提问作者xMilos
相关产品推荐
相关产品推荐

