Kotlin 实现 Map 列表合并 解决嵌套列表未展开异常问题
问题分析
你需要实现的是多Map合并逻辑,核心要求是相同键的值自动展平合并,单值保持String,多值返回List
原代码问题
- 第一阶段reduce分组时,没有对原始值做展平处理:如果输入Map中某个键的值本身就是List类型,会被当做单个元素存入分组后的List中,直接产生嵌套结构
- 类型强转逻辑不安全:你将分组后的value直接
as List<String>,但如果原始值是List的话,此时分组列表的元素类型实际是 Any(包含String和List),强转后会导致后续合并逻辑把整个List当做单个String处理 - fold阶段的合并逻辑没有对新加入的value做类型判断:如果新value本身是List,需要展开后再合并,而不是直接拼接整个List
优化实现
fun mergeMaps(maps: List<Map<String, *>>): Map<String, Any> { // 第一步:收集所有键对应的所有展平后的字符串值 val keyToValues = mutableMapOf<String, MutableList<String>>() maps.forEach { map -> map.forEach { (key, rawValue) -> // 把当前值统一展平为字符串列表 val valuesToAdd = when (rawValue) { is String -> listOf(rawValue) is List<*> -> rawValue.filterIsInstance<String>() else -> emptyList() // 可根据需求调整非String/List类型的处理逻辑 } // 追加到对应键的列表中,自动去重 keyToValues.getOrPut(key) { mutableListOf() } .addAll(valuesToAdd.filterNot { it in keyToValues.getValue(key) }) } } // 第二步:按照要求转换返回值格式,单值返回String,多值返回List<String> return keyToValues.mapValues { (_, values) -> if (values.size == 1) values.first() else values } }
测试验证
运行你给出的测试用例:
val map1 = mapOf("foo" to "bar", "test" to "test-value", "arrayTest" to listOf("foo", "bar")) val map2 = mapOf("biz" to "buz", "test" to "something-else", "arrayTest" to "baz") val mergedMaps = mergeMaps(listOf(map1, map2))
输出结果为:
{foo=bar, test=[test-value, something-else], arrayTest=[foo, bar, baz], biz=buz}
完全符合你的预期要求。
内容的提问来源于stack exchange,提问作者oxnard
相关产品推荐
相关产品推荐

