使阵列平坦,了解解决方案 [英] Making an array flat, understanding the solution

查看:83
本文介绍了使阵列平坦,了解解决方案的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我几天前发布了一个问题,关于如何在不使用 concat reduce 的情况下展平数组,我得到了一些很好的答案,但我仍然不完全理解我收到的解决方案。我将尽我对每一行的理解,也许有人可以指出我的推理错误的地方。

I posted a question a few days ago about how to flatten an array without using concat or reduce and I got some great answers but I still don't fully understand the solution I received. I will try and put my understanding of each line and maybe someone can point out where my reasoning is wrong.

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

好吧,首先

var l = array.length, temp;

这里l仅为2,所以我们的数组长度为2并且 temp 是2

here l is just 2 and so our array length is 2 and temp is 2

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

如果我们的数组位于位置 1 (因为我们递减了<$ c $ while 循环中的 1 中的c> l 确实是我们将执行的数组代码的下一部分

if our array at position 1 (since we decremented l by 1 in the while loop) is indeed an array we will execute the next part of the code

flatten(array[l]);

在这种情况下,我们需要继续操作,以防在数组中嵌套数组

Here we need to keep going in case we have nested arrays within an array

temp = array[l].slice();

因为切片没有参数 temp = array [1] ;所以现在 temp = ['4','5',['6'],['7','8']]]

since slice has no parameter temp = array[1]; so now temp = ['4', '5', ['6'], ['7', '8']]]

temp.unshift(1);

在温度开始处添加一个。 (不知道我们为什么要这么做,为什么要这样做)

Add one to the beginning of temp. (No idea why we are doing this, and why the number one)

temp.unshift(l);

因为 l 1 ,我们在数组的开头放置另一个 1

Since l is 1, we are putting another 1 at the beginning of the array.

现在 temp = [1,1,'4','5',['6'],['7','8']]

[]。splice.apply(array,temp);好吧,我真的不知道这条线在做什么。我一直在阅读文档,了解到 apply 可以让我们为 this 指定一个值,然后我们可以传递一些参数并且一个函数将运行(对于我所看到的示例),但是我不明白这里的用法是什么。再加上拼接,从索引 y 中取出 x 个元素,那么这些索引是什么?此处 splice 没有参数。以及开头 [] 中的空数组是什么。请帮助我了解我正在努力!

[].splice.apply(array, temp); ok I seriously have NO clue what this line is doing. I have been reading documentation and I understand that apply lets us specify a value for this and then we can pass some parameters and a function will run ( for the example I saw), however I can't understand what the heck is the usage here. Plus splice takes out x amount of elements from the index y, so what are these indices? here splice has no parameters. and whats with the empty array in the beginning []. Please help me understand I am trying really hard!

推荐答案

所以您的问题与代码的这一部分有关:

So your question is about this part of the code:

        temp.unshift(1);
        temp.unshift(l);
        [].splice.apply(array, temp);

从最后一条语句开始,它调用 splice 数组上,但以特定方式。通常,您会这样称呼它:

Starting with the last statement, it is calling splice on array, but in a specific way. Normally you would call it like this:

array.splice(l, 1, temp[0], temp[1], ...)

...表示:在索引 l 数组的code> ,删除1个元素,并插入 temp [0] temp [1] ,...等。问题是我们事先不知道 temp 中有多少个元素,但是仍然需要为 splice 提供尽可能多的参数。而且我们不能只传递 temp 作为参数,因为然后 array 插入的元素本身就是数组,这就是您要做的不是想要的。

... which means: at index l of array, delete 1 element, and insert temp[0], temp[1], ... etc. The problem is that we don't know beforehand how many elements there are in temp, but still need to provide as many arguments to splice. And we can't just pass temp as argument, because then array gets an element inserted that is an array itself, which is what you just do not want to do.

在ES6中,有一个简单的解决方案(见下文),在ES5中您可以在 splice 上使用 apply 解决此问题。该 apply 方法将应用该函数的对象作为第一个参数,然后接受一个数组,该数组具有所有需要传递给该函数的参数。

While in ES6 there is an easy solution for this (see below), in ES5 you can solve this by using apply on splice. That apply method accepts as first argument the object to apply the function on, and then an array which has all arguments that need to be passed to that function.

由于这些参数的前两个具有index的含义,以及在那里要删除的元素的数量(请参见上文),只有剩下的参数代表需要插入哪些元素( temp 中的那些),发生了所有这些变化:这些插入了两个第一个参数以传递给 splice

As the first two of those arguments have the meaning of index, and the number of elements to delete there (see above), and only then the remaining arguments represent which elements need to be inserted (those in temp), there is all this shifting happening: these insert the two first arguments to pass to splice.

然后剩下的参数就是 temp 中的原始参数(在转换之前)。您可以说 shift apply 语句执行以下操作:

Then the remaining arguments are what originally was in temp (before the shifting). You could say that the shift and apply statements do the following:

array.splice(temp[0], temp[1], temp[3], temp[4], ...)

请注意 temp 是如何为 all 现在争论。这就是为什么要移入前两个值的原因。它看起来很复杂,尽管可以工作,但不会导致代码可读性很强。

Note how temp is playing a role for all the arguments now. And that is why the first two values were shifted in. It looks complicated, and although it works, it does not result in very readable code.

现在在ES6中,它具有变得简单得多。现在,您可以使用spread运算符将数组分解为不同的参数,函数可以处理该数组:

Now in ES6 it has become much simpler. You can now use the spread operator to kind of explode an array into different arguments, and functions can deal with that:

array.splice(l, 1, ...temp)

由于我们不再需要移动了,我们可以放心地在没有变量 temp 的情况下直接在 array [l] 上执行此操作。因此完整的代码如下所示:

And since we don't need to shift anymore, we can safely do this without the variable temp, and directly on array[l]. So the complete code would look like this:

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


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

flatten(array);

console.log(array);

不是那个好简单吗? ;-)

Isn't that nice and simple? ;-)

这篇关于使阵列平坦,了解解决方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆