You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 13:55:14