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

Eloquent JavaScript第4章习题:listToArray递归返回空数组问题

链表转数组函数返回空数组问题修复

问题背景

实现对象结构链表与数组的互转功能时,listToArray函数设计逻辑为:遍历链表对象的属性,若属性值为数值类型则推入预先声明的空数组,若为非数值则将该属性作为参数传入递归调用,但最终函数始终返回空数组。要求不使用直接访问list.value、list.rest固定属性的写法。

原有问题代码

function arrayToList(array) {
  let list = null;
  for (let i = array.length - 1; i >= 0; i--) {
    list = {value: array[i], rest: list};
  }
  return list;
}

function listToArray(list) {
  let array = [];
  for (let i in list) {
    if(typeof list[i] == "number") {
        array.push(list[i]);
    } else if(typeof list[i] != "number") {
        return listToArray(list[i]);
    }
  }
  return array;
}

// 测试运行结果
console.log(arrayToList([10, 20]));
// 输出: {value: 10, rest: {value: 20, rest: null}}
console.log(listToArray(arrayToList([10, 20, 30])));
// 实际输出: []

错误原因

  • 递归逻辑错误:遍历到非数值属性时直接return递归调用结果,当前作用域内已经收集到的数值数组被直接丢弃,没有和递归返回的结果合并。
  • 缺失终止边界判断:链表末尾的终止标记是null,而typeof null返回值为"object",会被误判为需要递归的节点传入函数;对null执行for...in遍历不会进入循环体,直接返回空数组,这个空数组被逐层返回成为最终结果。

修复后代码

function listToArray(list) {
  let array = [];
  // 命中链表终止标记null,直接返回空数组
  if (list === null) {
    return array;
  }
  for (let i in list) {
    const currentVal = list[i];
    if (typeof currentVal === "number") {
      array.push(currentVal);
    } else if (typeof currentVal === "object" && currentVal !== null) {
      // 合并递归返回的后续节点数组,不直接return丢弃当前收集结果
      array = array.concat(listToArray(currentVal));
    }
  }
  return array;
}

修复后调用listToArray(arrayToList([10, 20, 30]))可正确返回[10, 20, 30],全程通过遍历属性完成逻辑,未直接访问固定属性名。


内容的提问来源于stack exchange,提问作者Tilek1990

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 18:31:00