You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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}

问题原因

  1. 异步延迟打乱执行顺序:使用Future.delayed将递归转为异步操作,破坏了同步遍历的顺序,导致打印内容错位(比如输出中的4flutter: {2, null}),甚至可能因上下文变化出现subRelation['subid']获取异常的情况。
  2. 递归逻辑重复且错误:在遍历每个子节点subRelation时,重复调用getIndexFromNestedList(relation['subRelatives']),导致同一个子节点数组被多次递归处理;正确的递归逻辑应该是处理完当前节点后,仅触发一次子数组的递归,而非在每个子节点循环内重复触发。
  3. 空数组判断不严谨:仅判断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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 19:36:03