Flutter中如何优雅实现API返回数据的映射?
优化API数据转TimeSeriesValues列表的冗余代码
问题背景
从API获取的数据结构如下:
[ { id: "19d4ab3b8d64c", score: 70, startTime: null, }, { id: "91e42b080ed6", score: 55, startTime: null, } ]
需要将其转换为List<TimeSeriesValues>类型,目标格式示例:
List<TimeSeriesValues> data = [ TimeSeriesValues(DateTime(2022, 2, 1, 00, 00), 30), // DateTime对应startTime,30对应score TimeSeriesValues(DateTime(2022, 2, 2, 23, 59), 80), ];
转换规则:
- 若
startTime为空,第一个元素使用当前时间,后续元素在前一个元素的时间基础上加24小时 - 若
startTime不为空,直接使用该时间
原实现代码冗余,且硬编码索引仅支持固定数量的元素:
List<TimeSeriesValues> list = []; if (data['list'][0]['startTime'] == null) { list.add(TimeSeriesValues(DateTime.now(), int.parse(data['list'][0]['score']))); } else { list.add(TimeSeriesValues(data['list'][0]['startTime'], 0)); } if (data['list'][1]['startTime'] == null) { list.add(TimeSeriesValues(DateTime(2022, 2, 1, 00, 00).add(const Duration(hours: 24)), int.parse(data['list'][1]['score']))); } else { list.add(TimeSeriesValues(data['list'][1]['startTime'], 0)); }
优化方案
优化后的代码
List<TimeSeriesValues> convertToTimeSeries(List<dynamic> apiList) { final result = <TimeSeriesValues>[]; DateTime? lastTimestamp; for (final item in apiList) { // 处理分数:将API返回的score转为int类型 final score = int.parse(item['score'].toString()); // 处理时间逻辑 final currentTimestamp = item['startTime'] != null ? item['startTime'] as DateTime : lastTimestamp == null ? DateTime.now() : lastTimestamp.add(const Duration(hours: 24)); result.add(TimeSeriesValues(currentTimestamp, score)); // 更新上一个时间戳,供下一个元素使用 lastTimestamp = currentTimestamp; } return result; } // 调用方式 final timeSeriesList = convertToTimeSeries(data['list']);
优化关键点
- 替代硬编码索引:通过循环遍历处理任意数量的元素,扩展性更强,无需为新增元素修改代码
- 复用时间逻辑:维护
lastTimestamp变量自动处理空值场景下的时间递增,避免手动计算每个元素的时间 - 修正逻辑错误:原代码中
else分支错误地将score设为0,优化后统一使用API返回的score值,符合转换规则 - 封装为独立函数:提高代码复用性,便于在多个地方调用,也方便后续维护和修改逻辑
内容的提问来源于stack exchange,提问作者newbie2210
相关产品推荐
相关产品推荐

