我在freeCodeCamp中制作压路机篝火 我无法弄清楚为什么我的代码无效 它只适用于数组中的第一个元素
function steamrollArray(arr) {
// I'm a steamroller, baby
var flat = [];
for( i=0; i < arr.length; i++ ){
if( Array.isArray(arr[i]) ){
flat = flat.concat(steamrollArray(arr[i]));
} else {
flat.push(arr[i]);
}
} // end of the for loop
return flat;
}
答案 0 :(得分:0)
正如@Jonathan所评论的那样,问题在于您使用的计数器i
未在函数中声明,因此是全局的。因此,递归调用将改变调用者的i
等。
function steamrollArray(arr) { // I'm a steamroller, baby var flat = []; for(var i=0; i < arr.length; i++ ){ if( Array.isArray(arr[i]) ){ flat = flat.concat(steamrollArray(arr[i])); } else { flat.push(arr[i]); } } // end of the for loop return flat; }
然而,第二个挑战是使代码在时间和内存上更高效。这可以通过将列表构造的数量限制为一个来完成。您可以使用名为 accumulator 的概念来执行此操作:通过递归过程更新的变量。首先,我们需要初始化变量:
function steamrollArray(arr) { return steamer(arr,[]); }
在这种情况下,累加器也是结果,我们将结果初始化为空数组。显然我们仍然需要实现steamer
函数:
function steamer (arr,target) { if(Array.isArray(arr)) { var n = arr.length; for(var i = 0; i < n; i++) { steamer(arr[i],target); } } else { target.push(arr); } return target; }
通过数组树的递归枚举传递目标是做什么的。如果值变为标量(Array.isArray
返回false
),我们将元素添加到target
的末尾;否则我们会执行递归调用。
此函数执行的最后一件事是返回target
,在初始steamer
调用之后,target
将填充嵌套列表中的所有元素。
优点是我们不需要昂贵的concat
函数,但只使用push
函数 O(n)次。如果我们抽象构造数组所需的处理时间(假设push
在O(1)时间内工作),那么算法现在可以在 O(n)时间和内存中使用< em> n 列表树中的叶子数。
答案 1 :(得分:0)
尝试使用以下方法递归数组,使用res []保存结果;
function steamrollArray(arr) {
var res=[];
function recurse(array)
{
for(var i = 0; i < array.length; i++)
{
if(!Array.isArray(array[i]))
res.push(array[i]);
else
recurse(array[i]);
}
}
recurse(arr);
return res;
}
答案 2 :(得分:0)
副作用,ES6,你可以使用.splice
function flatten(arr) {
let i = 0;
while (i < arr.length) {
if (Array.isArray(arr[i])) arr.splice(i, 1, ...arr[i]);
else ++i;
}
return arr;
}
e.g。使用
flatten([1, [2], [[3]], [4, [5, [6]]], [[[7], 8], 9]]);
// [1, 2, 3, 4, 5, 6, 7, 8, 9]
如果你不想要副作用,.slice
之前,
functon flatClone(arr) {
return flatten(arr.splice());
}
答案 3 :(得分:0)
function steamrollArray(arr) {
return String(arr).split(',').map(Number); }
如果它适用于所有情况,它适用于上面的“展平”示例,如果我错过了某些内容,请告诉我。
答案 4 :(得分:0)
这是我的代码,希望有帮助:
function steamrollArray(arr) {
let newArr = [];
//function:push every value in arr to newArr;
const getValue = function(elem) {
if(Array.isArray(elem)) {
elem.forEach(getValue);
}else{
newArr.push(elem);
}
}
arr.forEach(getValue);
console.log(newArr);
return newArr;
}
steamrollArray([[["a"]], [["b"]]]);