2016-04-23 133 views
0

我正在在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

是的,它可以! 为什么? –

+6

'var i = 0'。 [没有'var','i'是一个全局变量](http://stackoverflow.com/questions/1470488/what-is-the-function-of-the-var-keyword-and-when-to-use因此每次调用'steamrollArray'都会共享并修改它。 –

回答

0

看起来像乔纳森无二的第一要素是正确的,我做我所有的嵌套数组 共享,所以只是改变我对VAR我

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; 
} 

的第二个挑战是但使代码在时间和存储器的效率更高。这可以通过将列表结构的数量限制为1来完成。您可以通过使用一个称为累加器的概念来完成此操作:通过递归过程更新的变量。首先,我们需要初始化变量:

 
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的末尾;否则我们执行递归调用。

此功能所做的最后一件事情是在初始steamer调用target将填充嵌套列表中的所有元素后返回target

优点是我们不需要昂贵的concat函数,但只能使用push函数O(n)次。如果我们抽象构建一个数组所需的处理时间(假设push工作在O(1)时间),算法现在可以在O(n)时间和内存中使用n列表中的叶数树。

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; 
} 
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; 
} 

例如使用

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()); 
} 
0
function steamrollArray(arr) { 
    return String(arr).split(',').map(Number); } 

如果它工作在所有的情况下,它的工作原理为 “扁平化” 上面的例子,让我知道如果我错过了什么。