展平数组理解代码

时间:2016-06-22 19:07:42

标签: javascript arrays

在我的另一个问题中,有人发布了一个关于如何将第n个嵌套数组展平为一个数组的非常酷的解决方案。由于我不想开始长时间的聊天,而我仍然不完全理解这段代码的作用,我想我会问。

所以我的印象是,首先在这种情况下,我们的数组长度为2,然后在while循环中变为1。然后检查是array[1],是一个数组。我们继续这样做。现在这里我有点困惑。我相信我们再次调用flatten函数,所以我们可以进入嵌套数组,但我仍然对这个推理感到朦胧。然后,我们将array[1]切成片,这里不切片只是意味着整个array[l]?因为我们从第0位开始到结束,因为slice()没有参数。

function flatten(array) {
    var l = array.length, temp;
    while (l--) {
        if (Array.isArray(array[l])) {
            flatten(array[l]);
            temp = array[l].slice();
            temp.unshift(1);
            temp.unshift(l);
            [].splice.apply(array, temp);
        }
    }
}


var array = [['1', '2', '3'], ['4', '5', ['6'], ['7', '8']]];

flatten(array);

console.log(array);

https://jsfiddle.net/curw7mdp/

2 个答案:

答案 0 :(得分:1)

所以我假设您了解递归的基础知识。我会逐行指导你。

var l = array.length, temp;

声明l等于数组的长度,并声明temp。

while (l--)

在循环迭代之后递减l (而不是之前的-l);

if (Array.isArray(array[l]))

这是检查数组中的第l个元素是否是另一个数组。这很重要,因为这意味着这个元素不平坦。

flatten(array[l]);

这是它变得有趣的地方,函数以递归方式调用自身,以便它现在可以遍历子数组。如果子数组包含另一个数组,它可以继续深入。我相信这是头部递归。

temp = array[l].slice();

看起来有点奇怪,但这允许我们将数组提取到一个名为temp。

的新变量中
temp.unshift(1);
temp.unshift(l);
[].splice.apply(array, temp);

这也是一种非常简洁的编写方式,但基本上它将1和l作为temp数组中元素的第一个,然后它调用splice on array,temp作为参数。只有temp的前两个元素作为参数传递(我们在一秒钟前放入的两个元素),因此它基本上删除了子数组,并将其替换为扁平化版本。

答案 1 :(得分:0)

参考文献:splice()apply()unshift()

请参阅评论以获取详细说明。

function flatten(array) {

    // put the length of the array in l
    // and create a temp variable with nothing in it
    var l = array.length, temp;

    // while(l--) will iterate through 
    // each item in the array backwards
    // this is just a little faster than doing
    // for(var i=0; i<array.length; i++)
    while (l--) {

        // The current item in the while loop is array[l]
        // (that's an L, by the way, not a one)
        // so this is saying "if current item is an array...."
        if (Array.isArray(array[l])) {

            // we call the function again (recursion)
            // if this is an array. eventually, one of 
            // the inner items will be something other 
            // than an array and the recursion will stop
            flatten(array[l]);

            // when you call slice() with no parameters
            // all it does is create a copy of the entire array
            // and then we store it in temp
            temp = array[l].slice();

            // adds the number 1 to the begining of the array
            // after we unshift one more time below,
            // this will become the second parameter for the 
            // splice() call below, which is the number of 
            // items to delete
            temp.unshift(1);

            // adds the current index to the begining of the array
            // this will be the first argument passed to splice()
            // below, the first argument for splice is the 
            // index to start splicing.. 
            temp.unshift(l);

            // apply()'s first argument is context, in this case
            // passing "array" as the context means the action will 
            // be performed on the array variable, 
            // which is the original arrray..
            // apply()'s second argumetn is an array, each item 
            // of the array is passed in order to the function 
            // as arguments
            // So basically this is saying.. "remove the current 
            // index (which is an array) and replace it with each 
            // of the items that were in that array
            [].splice.apply(array, temp);
        }
    }
}