如何在Dart(RxDart)中将流的项收集为列表并通过另一个流暴露
问题描述
我定义了一个广播类型的StreamController:
final _controller = StreamController<List<LoadedPage<int, Entity>>>.broadcast();
还有一段获取分页数据并发送到流中的代码:
void getPagingData() async { final response = _api.getData(...); final pages = _convertResponseToPadingData(response); // 发送的pages结构示例: // <LoadedPage<int, Entity>>[ // LoadedPage(data: <Entity>[...]), // LoadedPage(data: <Entity>[...]), // LoadedPage(data: <Entity>[...]), // ] _controller.add(pages); }
现在需要实现一个entities getter,把流中每个事件里所有LoadedPage的data属性中的Entity项,合并成单个List<Entity>,再通过Stream<List<Entity>>暴露出去。比如3个页面各包含30个Entity,最终要输出一个包含90个Entity的列表到广播流中。
需要完成的代码:
Stream<List<Entity>> get entities { // 此处需要将Stream<List<LoadedPage<int,Entity>>> // 转换为Stream<List<Entity>> }
解决方案
可以通过Stream.map结合列表展开操作来实现,核心是把每个分页列表事件转换成扁平化的实体列表:
完整实现
Stream<List<Entity>> get entities { return _controller.stream.map((pages) { // 遍历所有页面,取出每个页面的data列表并合并成一个大列表 return pages.expand((page) => page.data).toList(); }); }
简洁写法
如果喜欢更紧凑的代码,也可以用箭头函数:
Stream<List<Entity>> get entities => _controller.stream.map((pages) => pages.expand((page) => page.data).toList());
代码说明
Stream.map:对流中的每个事件(即List<LoadedPage>)进行转换,生成新的流事件pages.expand((page) => page.data):将每个页面的data列表展开,把多个小列表合并成一个连续的可迭代对象toList():将可迭代对象转换为List<Entity>,作为新的流事件发送
这样每次_controller发送分页数据时,entities流就会自动输出合并了所有页面实体的完整列表。
内容的提问来源于stack exchange,提问作者BambinoUA
相关产品推荐
相关产品推荐

