Dart按ID匹配多数组实现站点路线关联算法报错如何解决
Dart路线站点匹配算法修复方案
错误根因
- 核心报错原因:函数存在逻辑分支无返回值,且循环内提前返回。如果
routes列表为空,函数没有执行return语句,最终返回null,你后续代码访问返回结果的第0位时,就触发了null调用[]方法的错误;即使routes不为空,第一次循环就直接返回,也只会返回最多1条数据,不符合需求。 - 类型不匹配:代码中定义
cards为List<FlightCard>,但模型RouteandStopsSearch的cards字段类型为List<RaceCard>,同时api.fetchRaceCard返回的应该是RaceCard类型集合,类型不一致会导致隐式转换异常。 - 空安全问题:
- 调用
variants.where(...).first时如果没有匹配到对应mrId的变体,会直接抛出无元素异常 - 模型类
RouteandStopsSearch的字段没有做可空声明或者late修饰,符合空安全规范的Dart版本会直接编译报错
- 调用
- 业务逻辑缺失:匹配到的站点列表
currentRoutes和班次卡数据没有赋值给RouteandStopsSearch实例的对应字段,后续访问这些字段会得到null。 - 变量命名冲突:内层循环变量和外层
cards列表同名,容易出现逻辑混淆。
修复后代码
模型类适配空安全
class RouteandStopsSearch{ late Routes route; late List <StopList> stop; late List <RaceCard> cards; late ScheduleVariants variant; // 也可以根据业务需要声明为可空类型:Routes? route; }
算法代码
Future<List<RouteandStopsSearch>> searchStops(int mv_id) async { // 修正类型匹配 List<RaceCard> cards = []; List<StopList> stopList = []; List<Routes> routes = []; List<ScheduleVariants> variants = []; cards.addAll(await api.fetchRaceCard(mv_id)); stopList.addAll(await api.fetchStops()); routes.addAll(await api.fetchroutes()); variants.addAll(await api.fetchSchedule()); List<RouteandStopsSearch> searchStops = []; // 提前过滤和当前mv_id匹配的变体,减少后续循环匹配开销 Map<int, ScheduleVariants> variantMap = { for (var v in variants) v.mrId: v }; // 提前根据st_id建立站点映射,提升匹配效率 Map<int, StopList> stopMap = { for (var s in stopList) s.stId: s }; for (Routes routelist in routes) { final searchStop = RouteandStopsSearch(); searchStop.route = routelist; // 处理匹配不到变体的情况,避免抛异常 if (!variantMap.containsKey(routelist.mrId)) { continue; } searchStop.variant = variantMap[routelist.mrId]!; // 匹配当前路线对应的站点 List<StopList> currentStops = []; List<RaceCard> currentCards = []; for (var card in cards) { if (stopMap.containsKey(card.stId)) { currentCards.add(card); currentStops.add(stopMap[card.stId]!); } } searchStop.stop = currentStops; searchStop.cards = currentCards; searchStops.add(searchStop); } // 循环结束后统一返回,提前返回放在循环内只会返回第一次循环的结果 return searchStops; }
额外注意事项
- 调用该方法时需要判断返回的列表是否为空,避免直接访问[0]触发数组越界
- 如果不需要返回所有路线的匹配结果,只需要返回和入参
mv_id匹配的路线,可以在循环前先对routes列表做过滤,减少不必要的循环 - 接口请求可以并行发起,提升接口响应速度:使用
Future.wait同时请求四个接口,不需要逐个await
内容的提问来源于stack exchange,提问作者user16357470
相关产品推荐
相关产品推荐

