如何高效将List<Car>按name属性分组为List<List<Car>>
按Car对象的name属性高效分组实现List<List>
你的现有代码逻辑存在问题:遍历每个Car时,每次都新建仅包含当前Car的子列表并加入结果,没有将同name的其他Car合并到同一个子列表中,因此最终每个Car单独成一个子列表。
高效实现方案(O(n)时间复杂度)
使用Map<String, List<Car>>作为中间容器,仅遍历一次原列表即可完成分组,适合处理大量数据:
List<List<Car>> groupCarsByName(List<Car> list) { final Map<String, List<Car>> groups = {}; for (final car in list) { // 若Map中无当前name对应的键,初始化空列表 groups.putIfAbsent(car.name, () => []); // 将当前Car添加到对应name的列表中 groups[car.name]!.add(car); } // 将Map的values转换为目标嵌套列表返回 return groups.values.toList(); }
更简洁的写法(使用fold)
可以通过fold方法简化Map的构建过程:
List<List<Car>> groupCarsByName(List<Car> list) { final groups = list.fold<Map<String, List<Car>>>({}, (map, car) { map.putIfAbsent(car.name, () => []); map[car.name]!.add(car); return map; }); return groups.values.toList(); }
测试验证
用你的示例数据测试:
void main() { List<Car> cars = [ Car(34, 'Micro'), Car(23, 'Micro'), Car(22, 'Tomsa'), Car(99, 'Tomsa'), Car(34, 'Tikka'), ]; final grouped = groupCarsByName(cars); print(grouped); } class Car { int age; String name; Car(this.age, this.name); @override String toString() { return 'Car: $age $name'; } }
输出结果:
[ [Car: 34 Micro, Car: 23 Micro], [Car: 22 Tomsa, Car: 99 Tomsa], [Car: 34 Tikka] ]
说明
- 该方案仅遍历原列表一次,时间复杂度为O(n),处理大规模数据时效率优异
- Dart 2.13及以上版本中,默认
Map会保留键的插入顺序,分组顺序与原列表中各name首次出现的顺序一致 - 如需自定义分组顺序,可对
groups.values.toList()进行二次排序
内容的提问来源于stack exchange,提问作者RobbB
相关产品推荐
相关产品推荐

