如何实现列表中Map键对应值的求和逻辑
How to Calculate Total Sales for Each Product from
List<Map<String, int>> 我懂你的需求啦——你要从一组结构为List<Map<String, int>>的销售记录里,统计每个产品的累计销量,但之前的代码因为产品在部分记录里不存在时会返回null,导致相加报错。咱们来解决这个问题。
先分析你原来代码的问题
你原来的代码里,e[element](这里应该是笔误,应该是e[productName])当产品不在当前销售记录的Map里时,会返回null,而null不能直接和int类型的previousValue相加,所以会抛出错误。解决的核心就是处理空值,把不存在的产品销量视为0。
方法1:修改你原来的实现
只需要在相加的时候用??运算符处理空值,当产品不存在时用0代替:
List<Map<String, int>> salesData = [ {'product A': 12, 'product B': 30, 'product C': 17, 'product K': 220}, {'product A': 3, 'product F': 2, 'product C': 10}, {'product F': 6, 'product S': 4, 'product A': 1}, {'product F': 1, 'product S': 11}, ]; Map<String, int> finalSaleData = {}; Set<String> mySet = {}; for (var element in salesData) { mySet.addAll(element.keys); } for (var productName in mySet) { // 用?? 0处理产品不存在的情况,避免null报错 finalSaleData[productName] = salesData.fold(0, (previousValue, e) => previousValue + (e[productName] ?? 0) ); } print(finalSaleData); // 输出:{product A: 16, product B: 30, product C: 27, product K: 220, product F: 9, product S: 15}
方法2:更高效的实现(推荐)
其实你不需要先收集所有产品名再逐个累加,直接遍历每一条销售记录的键值对,实时更新累计销量就好——这样只需要遍历一次数据,效率更高:
List<Map<String, int>> salesData = [ {'product A': 12, 'product B': 30, 'product C': 17, 'product K': 220}, {'product A': 3, 'product F': 2, 'product C': 10}, {'product F': 6, 'product S': 4, 'product A': 1}, {'product F': 1, 'product S': 11}, ]; Map<String, int> finalSaleData = {}; for (var saleRecord in salesData) { saleRecord.forEach((productName, quantity) { // 如果产品已经在结果里,就累加数量;否则初始化为当前数量 finalSaleData[productName] = (finalSaleData[productName] ?? 0) + quantity; }); } print(finalSaleData); // 同样得到正确的累计结果
这个方法的思路是:每遍历一条销售记录,就把这条记录里的每个产品销量加到结果Map对应的键上——如果产品是第一次出现,就用0 + 当前数量初始化它的累计值。
验证结果
用你给的示例数据,两种方法都会得到正确的累计值:
- product A: 12+3+1 = 16
- product B: 30
- product C:17+10=27
- product K:220
- product F:2+6+1=9
- product S:4+11=15
内容的提问来源于stack exchange,提问作者Aron
相关产品推荐
相关产品推荐

