我的问题逻辑,使用以下内容作为输入。
var input = [['A','B'],1,2,3,['C','D']]
当尝试使用递归展平嵌套数组时,该函数的输入变量不断得到重新分配,从而阻止了我使用原始数组再次调用该函数。如何防止重新分配原始输入变量?
我知道这不是完整的解决方案,但是当我将第一个元素移出嵌套数组时,我会陷入困境。
我已经逐步使用此功能,但是我必须缺少某些东西,另一双眼睛会很有帮助。
我也一直在使用chrome开发人员工具,设置断点来逐步监视功能。
//Defining original input variable
var input = [['A','B'],1,2,3,['C','D']]
function flat(array){
var result = []
var firstElement = array[0]
//CHECK IF FIRST ELEMENT IS ARRAY OR NOT
if(Array.isArray(firstElement)){
return flat(firstElement)
}
//IF ELEMENT NOT ARRAY, PUSH ELEMENT TO RESULT
else{result.push(firstElement)
array.shift() //removing child element
return (flat(array)) //call function on same array
}
if(array.length===0){return result}
}
第一次迭代: firstElement = ['A','B'],Array.isArray(firstElement)为true,因此调用flat(firstElement)
第二个迭代: firstElement ='A',Array.isArray(firstElement)为false,因此我们 1.跳下将这个元素推入结果 2.使用array.shift()删除“ A” 3.调用flat(array),其中array现在为['B']
第三次迭代: firstElement ='B',Array.isArray(firstElement)为false 1.向下跳转以将该元素推入结果,由于我在调用该函数时已重置结果,因此结果现在仅为['B']。 2.使用array.shift()删除“ B”,数组现在为空,-> [] 3.如何跳出并在原始输入数组上使用flat()?
答案 0 :(得分:1)
如果第一个元素是数组,则您的代码不会考虑以下元素。下面的解决方案使用array.concat(...)
来组合递归的结果(沿着树),还可以组合处理列表的其余部分(在同一级别)的结果。将问题可视化为一棵树,通常有助于IMO的递归:
[] 1 2 3 []
| |
A [] C D
|
B C
因此,也许在这里更清楚地表明,我们必须同时合并递归的结果和向右(再次递归)执行“ step”的结果,否则,这将是循环迭代数组。
var input = [['A',['B', 'C']],1,2,3,['C','D']]
function flat(array) {
var result = []
if (array.length == 0) return result;
if (Array.isArray(array[0])) {
result = result.concat(flat(array[0])); // Step down
} else {
result.push(array[0]);
}
result = result.concat(flat(array.slice(1))) // Step right
return result;
}
console.log(flat(input));
// ["A", "B", "C", 1, 2, 3, "C", "D"]
这有点类似于带有循环的版本:
function flat(array) {
var result = []
for (var i = 0; i < array.length; i++) {
if (Array.isArray(array[i])) {
result = result.concat(flat(array[i]));
} else {
result.push(array[i]);
}
}
return result;
}
编辑:出于调试目的,您可以跟踪深度,以帮助您大致了解发生的情况:
var input = [['A',['B', 'C']],1,2,3,['C','D']]
function flat(array, depth) {
var result = []
if (array.length == 0) return result;
if (Array.isArray(array[0])) {
result = result.concat(flat(array[0], depth + 1));
} else {
result.push(array[0]);
}
var res1 = flat(array.slice(1), depth);
console.log("Depth: " + depth + " | Concatenating: [" + result + "] with: [" + res1 + "]");
result = result.concat(res1)
return result;
}
console.log(flat(input, 0));
答案 1 :(得分:0)
如果要避免循环,而我正在考虑将数组{/ {1}}扩展/扩展为循环,则需要将结果数组传递给函数。
concat
答案 2 :(得分:0)
这是我的答案,如果您使用的是JavaScript
您可以使用下面的一行代码来展平n级嵌套数组
let flattendArray = input.flat(Infinity);
或通过reduce和concat使用这种方法
function flatDeep(arr, d = 1) {
return d > 0 ? arr.reduce((acc, val) => acc.concat(Array.isArray(val) ? flatDeep(val, d - 1) : val), [])
: arr.slice();
};