Dart中如何将List<BadgeItem>直接转为Map<String, BadgeItemDto>?
问题
在创建DTO时,需要将BadgeItem对象列表转换为Map<String, BadgeItemDto>类型。现有列表定义如下:
final List badgesList = [BadgeItem_1, BadgeItem_2, BadgeItem_3, ...];
希望直接在声明中生成Map<String, BadgeItemDto>? badges,但当前实现返回的是List<Map<String, BadgeItemDto>>,不符合要求:
return CardDto( badges: badgesList! .map( (badgeItem) => <String, BadgeItemDto>{ badgeItem.id: BadgeItemDto.fromDomain(badgeItem) }, ) );
期望的最终Map结构示例:
{ 'abcdefgh': BadgeItemDto(badgeId: '1234', badgeName: 'Lorem ipsum', ...), 'ztrewq': BadgeItemDto(badgeId: '6432', badgeName: 'Lorem ipsum', ...) }
附BadgeItemDto定义代码:
abstract class BadgeItemDto implements _$BadgeItemDto { const factory BadgeItemDto({ required String badgeId, required String badgeName, }) = _BadgeItemDto; factory BadgeItemDto.fromJson(Map<String, dynamic> json) => _$BadgeItemDtoFromJson(json); const BadgeItemDto._(); factory BadgeItemDto.fromDomain(BadgeItem badgeItem) { return BadgeItemDto( badgeId: badgeItem.id.getOrCrash(), badgeName: badgeItem.badgeName.getOrCrash(), ); } BadgeItem toDomain() { return BadgeItem( id: UniqueId.fromUniqueString(badgeId), badgeName: BadgeName(badgeName), ); } }
解决方案
可以通过两种常用方式直接生成目标Map:
方法1:使用fold方法
fold从初始空Map开始,逐个处理列表元素并累积成完整Map:
return CardDto( badges: badgesList?.fold<Map<String, BadgeItemDto>>( {}, (map, badgeItem) { map[badgeItem.id.getOrCrash()] = BadgeItemDto.fromDomain(badgeItem); return map; }, ), );
注意:
badgeItem.id是UniqueId类型,需调用getOrCrash()转为字符串作为Map的key,与BadgeItemDto.fromDomain的实现逻辑保持一致。
方法2:使用Map.fromEntries
先将列表元素转换为MapEntry对象,再通过fromEntries构建完整Map:
return CardDto( badges: badgesList?.map((badgeItem) => MapEntry( badgeItem.id.getOrCrash(), BadgeItemDto.fromDomain(badgeItem), )).let(Map.fromEntries), );
两种方法均能直接生成Map<String, BadgeItemDto>类型的结果,替代原返回List的map写法。
内容的提问来源于stack exchange,提问作者SRel
相关产品推荐
相关产品推荐

