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

Dart实现列表元素按Map键匹配分组时运行结果不符合预期

问题排查与修正

问题复现

现有一个所有键对应初始值为空列表的Map,以及一个存储多类数据的列表,需求是遍历数据列表,将与Map键匹配的元素添加到对应键的值列表中。
初始实现代码:

void main() {
  List list = [];
  var maps= { 
    'A' : [],
    'B' : [],
    'C' : [],
  };

  List y = ['A','B','C','A','B','C'];

  maps.forEach((key,values){
    List temp =[];
    for (var i in y){
      if(key == i) {
      list.add(i);
    } 
    temp = list;
  }
  maps[key] = temp;
  list.clear();
  print(maps);
 });
}

代码实际运行输出:

{A: [], B: [], C: []}

预期输出:

{A: [A,A], B: [B,B], C: [C,C]}

错误原因

  • 核心错误:Dart中List是引用类型,代码中temp = list只是让temp变量指向了list的内存地址,没有复制列表内容,后续执行list.clear()时,temp指向的同一块内存的内容会被同步清空,最终Map里所有键对应的值都是空列表。
  • 逻辑冗余:嵌套遍历效率极低,遍历Map每个键时都全量扫描一次数据列表,时间复杂度是O(n*m),完全可以优化到O(n)。
  • 无效代码:开头定义的List temp = []会被后续的temp = list直接覆盖,没有任何实际作用。

修正代码

推荐直接遍历待分类的数据列表,将元素直接追加到Map对应键的列表中,逻辑简洁且没有引用问题:

void main() {
  var maps = {
    'A': [],
    'B': [],
    'C': [],
  };
  List y = ['A', 'B', 'C', 'A', 'B', 'C'];

  for (final item in y) {
    // 判断item是Map的合法键后直接追加到对应列表
    maps[item]?.add(item);
  }

  print(maps); // 输出:{A: [A, A], B: [B, B], C: [C, C]}
}

如果需要保留原有嵌套遍历的写法,只需要在赋值时复制列表内容,不要直接传递引用即可(不推荐,效率更低):

void main() {
  List list = [];
  var maps= { 
    'A' : [],
    'B' : [],
    'C' : [],
  };

  List y = ['A','B','C','A','B','C'];

  maps.forEach((key,values){
    list.clear();
    for (var i in y){
      if(key == i) {
        list.add(i);
      } 
    }
    // 使用List.from创建新的列表实例,复制list的内容
    maps[key] = List.from(list);
  });
  print(maps);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 22:42:29