如何更简洁地对List<Map>去重并累加对应ID的数值?
更简洁的List
你的现有代码能实现需求,但嵌套循环的写法不仅冗余,数据量大时效率也偏低。这里提供几种更简洁高效的实现方式:
方案一:先统计再生成结果(推荐)
先遍历一次原列表统计每个ID的累计值,再根据指定的tagId列表生成最终结果,避免嵌套循环:
List tagId = ['a', 'b']; List oldList = [{'id': 'a', 'value': 1}, {'id': 'a', 'value': 1}, {'id': 'a', 'value': 1}, {'id': 'a', 'value': 1}, {'id': 'b', 'value': 1}, {'id': 'b', 'value': 1}]; // 统计每个ID的出现次数 final idCounter = <String, int>{}; for (final item in oldList) { final id = item['id'] as String; idCounter[id] = (idCounter[id] ?? 0) + 1; } // 根据tagId生成目标列表 final newList = tagId.map((id) => {'id': id, 'value': idCounter[id] ?? 0}).toList(); print(newList);
方案二:用fold函数式写法
利用fold方法一步完成统计,代码更紧凑:
List tagId = ['a', 'b']; List oldList = [{'id': 'a', 'value': 1}, {'id': 'a', 'value': 1}, {'id': 'a', 'value': 1}, {'id': 'a', 'value': 1}, {'id': 'b', 'value': 1}, {'id': 'b', 'value': 1}]; // 通过fold折叠列表生成统计Map final idCounter = oldList.fold<Map<String, int>>({}, (counterMap, item) { final id = item['id'] as String; counterMap[id] = (counterMap[id] ?? 0) + 1; return counterMap; }); final newList = tagId.map((id) => {'id': id, 'value': idCounter[id] ?? 0}).toList(); print(newList);
方案三:直接统计所有存在的ID(无需指定tagId)
如果不需要依赖外部的tagId列表,而是直接统计原列表中所有出现的ID,写法可以更简洁:
List oldList = [{'id': 'a', 'value': 1}, {'id': 'a', 'value': 1}, {'id': 'a', 'value': 1}, {'id': 'a', 'value': 1}, {'id': 'b', 'value': 1}, {'id': 'b', 'value': 1}]; final newList = oldList .fold<Map<String, int>>({}, (counterMap, item) { final id = item['id'] as String; counterMap[id] = (counterMap[id] ?? 0) + 1; return counterMap; }) .entries .map((entry) => {'id': entry.key, 'value': entry.value}) .toList(); print(newList);
这些方案的核心都是只遍历原列表一次完成统计,相比原代码的嵌套循环(时间复杂度O(n*m)),时间复杂度优化为O(n + m),数据量大时优势明显,同时代码结构更清晰易读。
内容的提问来源于stack exchange,提问作者ben
相关产品推荐
相关产品推荐

