在我的另一个问题中,有人发布了一个关于如何将第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);
答案 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);
}
}
}