Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/439.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript-用于展平数组的递归/for循环_Javascript_Arrays_Recursion - Fatal编程技术网

Javascript-用于展平数组的递归/for循环

Javascript-用于展平数组的递归/for循环,javascript,arrays,recursion,Javascript,Arrays,Recursion,因此,这里有一个解决阵列平坦问题的示例解决方案。我的问题不是“如何”展平阵列。相反,我试图理解在这个递归中发生的一些底层功能 此解决方案将遍历原始数组的每个元素,通过将这些元素放回函数分解为数组的所有元素,直到它们不再是数组并可以推送到新数组 我的问题是,“for”循环如何跟踪元素通过函数返回的所有时间,以及如何继续循环它当时正在处理的“原始”数组的其余部分?它必须以某种方式保持跟踪,否则每次元素是数组并被放回时,当前循环都会被缩短。希望我的问题有意义 function steamrollArr

因此,这里有一个解决阵列平坦问题的示例解决方案。我的问题不是“如何”展平阵列。相反,我试图理解在这个递归中发生的一些底层功能

此解决方案将遍历原始数组的每个元素,通过将这些元素放回函数分解为数组的所有元素,直到它们不再是数组并可以推送到新数组

我的问题是,“for”循环如何跟踪元素通过函数返回的所有时间,以及如何继续循环它当时正在处理的“原始”数组的其余部分?它必须以某种方式保持跟踪,否则每次元素是数组并被放回时,当前循环都会被缩短。希望我的问题有意义

function steamrollArray(array) {
  var flatArray = [];

  flatten(array);

  function flatten(array) {
    for (var i = 0; i < array.length; i++) {
      if (Array.isArray(array[i])) {
        flatten(array[i]);
      } else {
        flatArray.push(array[i]);
      }
    }
  }

  return flatArray;
}
steamrollArray([1, [2], [3, [[4]]]]);
函数数组(数组){
var flatArray=[];
展平(阵列);
函数展平(数组){
对于(var i=0;i
它实际上并不会通过只发生一次的函数“返回”元素。它检查元素是否为数组,然后在该数组中循环

如果不是数组,则将其推送到
flatArray
。这里的递归是,如果任何元素是数组,那么它将通过展平函数。然后,若该数组中有一个元素,那个么该元素被发送到一个数组中,以此类推

让我们举一个例子:
[1,2],[3,[[4]]]]

我们开始循环->

  • 索引0是1而不是数组,因此它被推送到flatArray
  • 索引1是一个数组,所以我们递归-在这里我们有一个2-然后被推
  • 索引2是一个数组,所以我们递归,内部数组的索引0是一个非数组3,所以它被推送。然后我们有最后一个索引-一个数组,我们递归到其中,找到另一个数组-再次递归-最后得到4,我们推

我认为会有更好的答案,但接下来

至少,不要认为它“破坏”了循环,而是认为它继续按照过程顺序执行代码。因此,在循环的上下文中,它将自己作为函数调用,当该函数完成时,它将继续在循环中。范例

var item = [1, [2, 3], 4]
展平(项目)
的执行将是:

Loop 1: 
  Push 1
Loop 2: 
  Start a call to flatten with [2, 3]
  Loop 1: 
    push 2
  Loop 2: 
    push 3
  End loop
Loop 3: 
  Push 4
End Loop.
关键是,它只是执行一个步骤的过程。它不必“记住”它在哪里,当函数返回时,javascript只是从调用函数的地方继续处理


你可能希望复习一下

结果数组
flatary
位于helper函数的词法闭包中,因此非数组的元素被推到这个位置,它们在结果中的放置顺序与它们的迭代顺序相同

当其中一个元素是数组时,它调用
flatte(array[i])
,在返回之前将该元素的元素展平。与所有函数一样,语句的执行需要在下一个语句完成之前完成,调用函数根本不会取消当前函数。它将继续运行,直到结束或返回
语句

想象一下这个功能:

function test () {
  console.log("hello, ");
  console.log("world!");
}

调用该语句时,它会等待整个
console.log(“hello,”)
完成,然后再执行语句二(
console.log(“world!”)
)。若它是递归调用,那个么该调用需要在执行语句2之前完成。它适用于所有函数调用,不只是递归调用

每个递归步骤的“跟踪”与任何其他方法调用的工作方式相同;javascript引擎跟踪变量和作用域,无论何时在中调用新方法

对于您的特定示例,当
flant
函数不再嵌套时,可能更容易看到发生了什么

function steamrollArray(array) {
  var flatArray = [];
  flatten(array, flatArray);
  return flatArray;
}

function flatten(array, flatArray) {
  flatArray = flatArray || [];

  for (var i = 0; i < array.length; i++) {
    if (Array.isArray(array[i])) {
      flatten(array[i]);
    } else {
      flatArray.push(array[i]);
    }
  }
}

steamrollArray([1, [2], [3, [[4]]]]); # [1, 2, 3, 4]

现在更明显的是递归发生的位置和方式。每当一个数组被“发现”时,它也会被展平。将值推送到新数组中,或推送到作为第二个参数传递的数组中。每次在
for
循环中调用
flatten
时,位于
i
位置的数组本身被展平并推到
flatArray
上。由于
flatArray
也会递归地传递给
flat
函数,因此所有值都将被收集到该数组中。

我有一个更简单的解决方案,可用于数组中的任何嵌套级别

function flattenArray(arr){

  for(var i=0;i<arr.length;i++){

    if(arr[i] instanceof Array){

      Array.prototype.splice.apply(arr,[i,1].concat(arr[i]))
       i--;
    }

  }

  return arr;
}
函数阵列(arr){

对于(var i=0;i使用
循环以及其他两种方法展平阵列的解决方案

使用进行循环的操作

let数组=[1,2],[3,4]];
让输出=[];
让数组=(arr)=>{
对于(让一个arr){
数组.isArray(a)?数组(a):输出.push(a);
}
返回输出;
}

console.log(数组(数组));
它遍历数组项,如果数组的当前项是数组,它将该数组项作为参数递归调用展平函数,直到它不是数组而是整数。然后它将其推送到称为flatarray的外部数组,返回并继续上一个数组的下一项。会问很多问题在本主题中,首先:“它必须以某种方式跟踪”-当您从
f1()
中调用函数
f2()
时,然后在
f2()
完成
f1()后
在它停止的地方继续。因此,如果你从循环中调用函数,那么当函数完成时,循环将继续。在你的例子中,函数递归地调用自己
function flattenArray(arr){

  for(var i=0;i<arr.length;i++){

    if(arr[i] instanceof Array){

      Array.prototype.splice.apply(arr,[i,1].concat(arr[i]))
       i--;
    }

  }

  return arr;
}