如何在Dart中按相同sellerId合并数组并汇总数据?
在Dart中按sellerId合并产品数组的实现方法
原始输入数据
现有如下Dart格式的动态数组info:
const List<Map<String, dynamic>> info = [ { "productId": "1", "name": "This is product name 1", "sellerId": "12", "price": 30, }, { "productId": "2", "name": "This is product name 2", "sellerId": "12", "price": 50 }, { "productId": "3", "name": "This is product name 3", "sellerId": "13", "price": 50 } ];
需求说明
需要将该数组按sellerId合并,把同一sellerId的产品归入productIds数组,并计算对应总价,最终得到如下结构的结果:
const List<Map<String, dynamic>> result = [ { "sellerId": "12", "productIds": [ { "name": "This is product name 1", "productId": "1" }, { "name": "This is product name 2", "productId": "2" } ], "total": 80 }, { "sellerId": "13", "productIds": [ { "name": "This is product name 3", "productId": "3" } ], "total": 50 } ];
实现方法
方法一:使用Map快速分组(适合简单场景)
通过Map以sellerId为键进行分组,遍历原始数组完成数据聚合:
void main() { const List<Map<String, dynamic>> info = [ { "productId": "1", "name": "This is product name 1", "sellerId": "12", "price": 30, }, { "productId": "2", "name": "This is product name 2", "sellerId": "12", "price": 50 }, { "productId": "3", "name": "This is product name 3", "sellerId": "13", "price": 50 } ]; // 初始化分组容器,key为sellerId,value为对应分组数据 final Map<String, Map<String, dynamic>> groupedData = {}; for (final product in info) { final sellerId = product["sellerId"] as String; // 首次遇到该sellerId时,初始化分组结构 if (!groupedData.containsKey(sellerId)) { groupedData[sellerId] = { "sellerId": sellerId, "productIds": <Map<String, dynamic>>[], "total": 0, }; } // 添加产品信息到productIds数组 groupedData[sellerId]!["productIds"].add({ "productId": product["productId"], "name": product["name"], }); // 累加总价 groupedData[sellerId]!["total"] = (groupedData[sellerId]!["total"] as int) + (product["price"] as int); } // 将分组后的Map转换为目标List结构 final List<Map<String, dynamic>> result = groupedData.values.toList(); // 打印验证结果 print(result); }
方法二:使用类封装(符合Dart强类型特性,适合大型项目)
定义对应的数据类来封装数据,提升代码可读性和可维护性:
1. 定义数据类
// 原始产品数据类 class Product { final String productId; final String name; final String sellerId; final int price; Product({ required this.productId, required this.name, required this.sellerId, required this.price, }); // 从Map转换为Product实例 factory Product.fromMap(Map<String, dynamic> map) { return Product( productId: map["productId"] as String, name: map["name"] as String, sellerId: map["sellerId"] as String, price: map["price"] as int, ); } } // 分组后的卖家数据类 class SellerGroup { final String sellerId; final List<Map<String, dynamic>> productIds; int total; SellerGroup({ required this.sellerId, required this.productIds, required this.total, }); // 转换为目标Map格式 Map<String, dynamic> toMap() { return { "sellerId": sellerId, "productIds": productIds, "total": total, }; } }
2. 实现分组逻辑
void main() { const List<Map<String, dynamic>> info = [ { "productId": "1", "name": "This is product name 1", "sellerId": "12", "price": 30, }, { "productId": "2", "name": "This is product name 2", "sellerId": "12", "price": 50 }, { "productId": "3", "name": "This is product name 3", "sellerId": "13", "price": 50 } ]; // 将原始Map列表转换为Product实例列表 final List<Product> products = info.map((map) => Product.fromMap(map)).toList(); final Map<String, SellerGroup> groupedData = {}; for (final product in products) { if (!groupedData.containsKey(product.sellerId)) { groupedData[product.sellerId] = SellerGroup( sellerId: product.sellerId, productIds: [], total: 0, ); } // 添加产品摘要信息 groupedData[product.sellerId]!.productIds.add({ "productId": product.productId, "name": product.name, }); // 累加总价 groupedData[product.sellerId]!.total += product.price; } // 转换为目标List结构 final List<Map<String, dynamic>> result = groupedData.values.map((group) => group.toMap()).toList(); print(result); }
两种方法对比
- Map分组法:实现简单快速,代码量少,适合临时数据处理或小型项目;
- 类封装法:强类型约束,代码可读性、可维护性更高,便于后续扩展,适合中大型项目。
内容的提问来源于stack exchange,提问作者Jocalo
相关产品推荐
相关产品推荐

