Flutter中通过ID关联嵌套数组遇异常,递归函数输出不符预期求助
嵌套数组递归遍历异常:输出{2, null}而非预期{2,3}、{2,4}的问题排查与解决
我有一个嵌套结构的数组,编写了递归函数getIndexFromNestedList用于遍历数组并通过subid关联父子节点,但运行后出现{2, null}这类异常结果,预期应输出{2,3}、{2,4}这类正确的ID关联对,以下是详细信息及问题分析、解决方法:
数据示例
var sendlocal = [ { "firstName": "tree", "lastName": "tree", "relativeEmail": "tree@gmail.com", "relativeType": 0, "subid": 1, "subRelatives": [ { "firstName": "julia2", "lastName": "Michle", "relativeEmail": "test@hotmail.com3", "relativeType": 2, "subid": 2, "subRelatives": [ { "firstName": "john", "lastName": "bravo", "relativeEmail": "johny@gmail.com", "relativeType": 1, "subRelatives": [], "subid": 3, }, { "firstName": "simith", "lastName": "bravo", "relativeEmail": "johny@gmail.com", "relativeType": 1, "subRelatives": [], "subid": 4, }, ], }, { "firstName": "julia3", "lastName": "Michle", "relativeEmail": "test3@hotmail.com", "relativeType": 2, "subRelatives": [], "subid": 5, }, ], }, ];
编写的函数
getIndexFromNestedList(List<dynamic> mapValue) { if (mapValue != null) { for (var relation in mapValue) { print(relation['subid']); print(relation['relativeEmail']); if (relation['subRelatives'] != null) { for (var subRelation in relation['subRelatives']) { print({relation['subid'], subRelation['subid']}); // graph.addEdge(relation['subid'], subRelation['subid']); //like this Future.delayed(Duration(milliseconds: 1), () { getIndexFromNestedList(relation['subRelatives']); }); } } } } }
调用方式
var check = getIndexFromNestedList(relatives);
实际输出
flutter: {1, 2} flutter: {1, 3} 4flutter: {2, null}
问题原因
- 异步延迟打乱执行顺序:使用
Future.delayed将递归转为异步操作,破坏了同步遍历的顺序,导致打印内容错位(比如输出中的4flutter: {2, null}),甚至可能因上下文变化出现subRelation['subid']获取异常的情况。 - 递归逻辑重复且错误:在遍历每个子节点
subRelation时,重复调用getIndexFromNestedList(relation['subRelatives']),导致同一个子节点数组被多次递归处理;正确的递归逻辑应该是处理完当前节点后,仅触发一次子数组的递归,而非在每个子节点循环内重复触发。 - 空数组判断不严谨:仅判断
relation['subRelatives'] != null,但空数组[]会通过该判断,虽然不会触发循环,但逻辑上存在冗余。
解决方法
修正后的函数代码
getIndexFromNestedList(List<dynamic>? mapValue) { if (mapValue == null || mapValue.isEmpty) return; for (var relation in mapValue) { // 打印当前节点信息(可选,按需保留) print(relation['subid']); print(relation['relativeEmail']); final subRelatives = relation['subRelatives'] as List<dynamic>?; if (subRelatives != null && subRelatives.isNotEmpty) { // 遍历子节点,生成父子ID关联对 for (var subRelation in subRelatives) { final parentId = relation['subid']; final childId = subRelation['subid']; print({parentId, childId}); // graph.addEdge(parentId, childId); // 实际业务代码保留 } // 递归遍历子节点数组,处理更深层级的关联 getIndexFromNestedList(subRelatives); } } }
关键优化点
- 移除
Future.delayed,恢复同步递归,保证执行顺序稳定。 - 调整递归触发时机:遍历完当前节点的所有子节点后,仅调用一次递归处理子节点数组,避免重复操作。
- 完善空值判断:同时校验数组是否为空,避免无意义的逻辑进入。
- 增加变量提取和类型转换,提升代码可读性与稳定性。
内容的提问来源于stack exchange,提问作者Umaiz Khan
相关产品推荐
相关产品推荐

