Dart中如何将List<Model>转为自定义数据?求便捷实现方案
问题:如何简便地将List转换为目标模型数据?
模型定义
class Account { String name; double balance; Account({required this.name, required this.balance}); } class CategoryAccount { String type; List<Account> items; CategoryAccount({required this.type, required this.items}); }
源数据
List<Account> sourceData = [ Account(name: 'cash', balance: 100), Account(name: 'cash', balance: 200), Account(name: 'bank', balance: 300), Account(name: 'creditor', balance: 400), ];
期望转换结果
List<CategoryAccount> finalData = [ CategoryAccount( type: 'cash', items: [ Account(name: 'cash', balance: 100), Account(name: 'cash', balance: 200), ], ), CategoryAccount( type: 'bank', items: [ Account(name: 'bank', balance: 300), ], ), CategoryAccount( type: 'creditor', items: [ Account(name: 'creditor', balance: 400), // 注:原示例中此处为300,应为笔误,修正为源数据对应的400 ], ), ];
尝试过asMap()方法,但它以列表索引为键,不符合需求。请问Dart标准库中有合适的方法实现该转换吗?
解决方案
Dart标准库没有直接提供分组转换的API,但可以借助Map完成分组后再转成目标列表,代码简洁高效:
基础实现方式
// 1. 按Account.name分组,聚合同类型的Account Map<String, List<Account>> groupedAccounts = {}; for (var account in sourceData) { // 若key不存在则创建空列表,再添加当前Account groupedAccounts.putIfAbsent(account.name, () => []).add(account); } // 2. 将分组后的Map转换为CategoryAccount列表 List<CategoryAccount> finalData = groupedAccounts.entries.map((entry) { return CategoryAccount(type: entry.key, items: entry.value); }).toList();
链式调用简化版
如果偏好更紧凑的写法,可以用fold方法链式处理:
List<CategoryAccount> finalData = sourceData .fold<Map<String, List<Account>>>( {}, (map, account) => map..putIfAbsent(account.name, () => []).add(account), ) .entries .map((entry) => CategoryAccount(type: entry.key, items: entry.value)) .toList();
关键方法说明
putIfAbsent:核心分组逻辑,检查Map中是否存在指定key(即Account的name),不存在则通过回调创建空列表,随后将当前Account加入对应列表map:将Map的每个键值对(entry)转换为CategoryAccount实例,最终通过toList()得到目标列表
内容的提问来源于stack exchange,提问作者Answer_K
相关产品推荐
相关产品推荐

