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
相关产品推荐
相关产品推荐

