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

Flutter/Dart 如何按列表元素属性合并并执行对应汇总操作

Dart/Flutter 食材用量合并实现方案

实现思路

  1. 对原始列表按name属性分组,将同名称的食材归为一组
  2. 每组内再按unit属性二次分组,相同单位的用量累加
  3. 将同组内不同单位的用量字符串用+拼接,生成最终的total字段
  4. 整理成要求的输出结构即可

完整代码实现

1. 定义数据模型(可选,也可直接用Map操作)

class Ingredient {
  final String name;
  final String quantity;
  final String unit;

  Ingredient({
    required this.name,
    required this.quantity,
    required this.unit,
  });

  // 从Map创建对象
  factory Ingredient.fromMap(Map<String, String> map) {
    return Ingredient(
      name: map['name']!,
      quantity: map['quantity']!,
      unit: map['unit']!,
    );
  }
}

// 输出结构的模型
class MergedIngredient {
  final String name;
  final String total;

  MergedIngredient({required this.name, required this.total});

  // 转成Map输出
  Map<String, String> toMap() {
    return {
      'name': name,
      'total': total,
    };
  }
}

2. 核心处理逻辑

void main() {
  // 原始测试数据
  final List<Map<String, String>> rawList = [
    {"name": 'olive oil', "quantity": "1", "unit": "spoons"},
    {"name": 'olive oil', "quantity": "2", "unit": "spoons"},
    {"name": 'parmesan cheese', "quantity": "20", "unit": "slices"},
    {"name": 'parmesan cheese', "quantity": "3/4", "unit": "cup"},
    {"name": 'salt', "quantity": "1", "unit": "teaspoon"},
  ];

  // 转成模型列表操作
  final List<Ingredient> ingredients = rawList.map((e) => Ingredient.fromMap(e)).toList();

  // 第一步:按name分组
  final Map<String, List<Ingredient>> nameGroups = {};
  for (var ing in ingredients) {
    if (!nameGroups.containsKey(ing.name)) {
      nameGroups[ing.name] = [];
    }
    nameGroups[ing.name]!.add(ing);
  }

  // 第二步:处理每一组的用量
  final List<MergedIngredient> mergedList = [];
  nameGroups.forEach((name, ingList) {
    // 按unit二次分组,统计同单位总用量
    final Map<String, num> unitQuantityMap = {};
    // 存无法直接计算的分数用量(示例里的3/4这种)
    final List<String> specialUnits = [];

    for (var ing in ingList) {
      // 尝试把用量转成数值计算,转失败的直接拼接
      final num? quantity = num.tryParse(ing.quantity);
      if (quantity != null) {
        unitQuantityMap[ing.unit] = (unitQuantityMap[ing.unit] ?? 0) + quantity;
      } else {
        specialUnits.add("${ing.quantity} ${ing.unit}");
      }
    }

    // 拼接所有用量
    final List<String> totalParts = [];
    unitQuantityMap.forEach((unit, totalQty) {
      totalParts.add("$totalQty $unit");
    });
    totalParts.addAll(specialUnits);

    mergedList.add(MergedIngredient(
      name: name,
      total: totalParts.join(" + "),
    ));
  });

  // 输出结果
  final output = mergedList.map((e) => e.toMap()).toList();
  print(output);
}

运行输出

运行后输出的结果和预期完全一致:

[
  {name: olive oil, total: 3 spoons},
  {name: parmesan cheese, total: 20 slices + 3/4 cup},
  {name: salt, total: 1 teaspoon}
]

扩展说明

如果需要支持分数的运算(比如同单位的1/2和1/4相加得到3/4),可以引入第三方库处理分数的解析和计算,替换掉现有代码里的数值解析逻辑即可。

内容的提问来源于stack exchange,提问作者Rod

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 12:48:03