使用 JavaScript 将数组转换为列表
Turn Array Into List With JavaScript
我正在通读 Eloquent JavaScript,在第 4 章的末尾,它挑战您将数组转换为列表,即
[1, 3, 3] --> {value: 1, rest: {value: 2, rest: {value: 3, rest: null}}};
而且我不认为我理解这个概念。
它建议通过数组向后迭代,所以我尝试过:
function arrayToList(array) {
let list = {};
for (let i = array.length -1; i > array[0]; i--) {
list += ("value:" + i + ", rest: null");
}
return list;
}
console.log(arrayToList([1, 2, 3]));
然后注销:
[object Object]value:2, rest: null
如您所见,我不了解如何使用迭代创建 "nested" 对象(列表)。有人可以给我解释一下吗?
您需要从 null
作为第一个 list
值开始。
然后您需要遍历索引从最后到零的元素,并分配一个新的 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;
}
console.log(arrayToList([1, 2, 3]));
您可以大大简化您的代码。
有两种情况:要么数组为空,在本例中转换为 null
,要么不为空,在本例中只有第一个值很重要,其余的可以递归处理阵列。这是一个班轮。
const converter = arr => arr.length ? ({value: arr[0], rest: converter(arr.filter((_,i) => i>0))}) : null;
console.log(converter(['a', 'b', 'c']));
通过前向迭代,你可以做这样的事情。迭代数组,在每次迭代中定义嵌套对象,直到到达最后一个元素,当到达最后一个元素时,将 属性 定义为 null
.
let data = [1, 3, 3];
let res = {};
for (let i = 0, obj = res; i < data.length; i++) {
obj.value = data[i];
obj = obj.rest = i < data.length - 1 ? {} : null;
}
console.log(res)
这可能是一个非常适合递归方法的问题:
function arrayToList(array)
{
if (array.length <= 0)
return null;
return {value: array[0], rest: arrayToList(array.slice(1))};
}
console.log(arrayToList([1, 2, 3]));
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
我认为您对代码中出现问题的原因有很好的答案,但以防万一您感兴趣,这是 reduceRight()
的一个非常好的用例
let a = [1, 3, 3]
let l = a.reduceRight((rest, val) => ({val, rest}), null)
console.log(l)
它或多或少与您的代码所做的相同 — 从 null
开始并在列表中向后循环,同时将先前的结果编译到 rest
属性 中。
我正在通读 Eloquent JavaScript,在第 4 章的末尾,它挑战您将数组转换为列表,即
[1, 3, 3] --> {value: 1, rest: {value: 2, rest: {value: 3, rest: null}}};
而且我不认为我理解这个概念。
它建议通过数组向后迭代,所以我尝试过:
function arrayToList(array) {
let list = {};
for (let i = array.length -1; i > array[0]; i--) {
list += ("value:" + i + ", rest: null");
}
return list;
}
console.log(arrayToList([1, 2, 3]));
然后注销:
[object Object]value:2, rest: null
如您所见,我不了解如何使用迭代创建 "nested" 对象(列表)。有人可以给我解释一下吗?
您需要从 null
作为第一个 list
值开始。
然后您需要遍历索引从最后到零的元素,并分配一个新的 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;
}
console.log(arrayToList([1, 2, 3]));
您可以大大简化您的代码。
有两种情况:要么数组为空,在本例中转换为 null
,要么不为空,在本例中只有第一个值很重要,其余的可以递归处理阵列。这是一个班轮。
const converter = arr => arr.length ? ({value: arr[0], rest: converter(arr.filter((_,i) => i>0))}) : null;
console.log(converter(['a', 'b', 'c']));
通过前向迭代,你可以做这样的事情。迭代数组,在每次迭代中定义嵌套对象,直到到达最后一个元素,当到达最后一个元素时,将 属性 定义为 null
.
let data = [1, 3, 3];
let res = {};
for (let i = 0, obj = res; i < data.length; i++) {
obj.value = data[i];
obj = obj.rest = i < data.length - 1 ? {} : null;
}
console.log(res)
这可能是一个非常适合递归方法的问题:
function arrayToList(array)
{
if (array.length <= 0)
return null;
return {value: array[0], rest: arrayToList(array.slice(1))};
}
console.log(arrayToList([1, 2, 3]));
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
我认为您对代码中出现问题的原因有很好的答案,但以防万一您感兴趣,这是 reduceRight()
let a = [1, 3, 3]
let l = a.reduceRight((rest, val) => ({val, rest}), null)
console.log(l)
它或多或少与您的代码所做的相同 — 从 null
开始并在列表中向后循环,同时将先前的结果编译到 rest
属性 中。