Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/460.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.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:使用递归就地展平多维数组_Javascript_Arrays_Recursion_Multidimensional Array_Flatten - Fatal编程技术网

Javascript:使用递归就地展平多维数组

Javascript:使用递归就地展平多维数组,javascript,arrays,recursion,multidimensional-array,flatten,Javascript,Arrays,Recursion,Multidimensional Array,Flatten,我有下面的代码可以展平多维数组 var x = [[[2, 3], 4], 5, [6, 7]]; function flatten(arr) { for (var i = 0; i < arr.length; i++) { if (arr[i].constructor === Array) { subArr = arr[i]; // Shift the array down based on the space needed for the sub

我有下面的代码可以展平多维数组

var x = [[[2, 3], 4], 5, [6, 7]];

function flatten(arr) {

  for (var i = 0; i < arr.length; i++) {
    if (arr[i].constructor === Array) {
      subArr = arr[i];
      // Shift the array down based on the space needed for the sub array
      for (var j = arr.length + subArr.length - 2; j > i + subArr.length - 1; j--) {
        arr[j] = arr[j - subArr.length + 1];
      }
      // Insert sub array elements where they belong
      for (var k = 0; k < subArr.length; k++) {
        arr[i + k] = subArr[k]; 
      }
      // Look at arr[i] again in case the first element in the subarray was another array;
      i--;
    }
  }
}

flatten(x);

这是一个完全就地工作的纯递归版本,不构建中间数组

// Deep-flatten an array starting at index `i`.
function flatten(a, i = 0) {                                                                              

  if (i >= a.length)                                                                                      
    // Null case--we are off the end of the array.                                                        
    return;                                                                                               

  var elt = a[i];                                                                                         

  if (!Array.isArray(elt))                                                                                
    // Element is not an array. Proceed to next element.                                                  
    i++;                                                                                                  

  else                                                                                                    
    // Element is an array.                                                                               
    // Unroll non-empty arrays; delete empty arrays.                                                      

    if (elt.length) {                                                                                     
      // Non-empty array.                                                                                 
      // Unroll it into head and tail.                                                                    

      // Shift elements starting at `i` towards end of array.
      // Have to do this recursively too--no loops!                                             
      (function shift(a, i, n = a.length) {                                                               
        if (n > i ) a[n] = a[n-1], shift(a, i, --n);                                                      
      }(a, i));                                                                                           

      // Replace elt with its head, and place tail in slot we opened up.                                  
      a[i] = elt.shift();                                                                                 
      a[i + 1] = elt;                                                                                     
    }                                                                                                     

  else                                                                                                    
    // Array is empty.                                                                                    
    // Delete the element and move remaining ones toward beginning of array. 
    // Again, have to do this recursively!                             
    (function unshift(a, i) {                                                                             
      if (i < a.length) a[i] = a[i+1], unshift(a, ++i);                                                   
      else a.length--;                                                                                    
    }(a, i));                                                                                             

  flatten(a, i);                                                                                          

}                                                                                                         

var arr = [[[2, 3], 4], 5, [6, 7]];                                                                   
flatten(arr);                                                                                             
console.log(arr);                                                                                         

[2, 3, 4, 5, 6, 7]         
//深度展平从索引'i'开始的数组。
函数展平(a,i=0){
如果(i>=a.length)
//Null case——我们已经离开了数组的末尾。
返回;
var elt=a[i];
if(!Array.isArray(elt))
//元素不是数组。请转至下一个元素。
i++;
其他的
//元素是一个数组。
//展开非空数组;删除空数组。
if(elt.length){
//非空数组。
//把它展开成头和尾。
//将从“i”开始的元素移到数组的末尾。
//也必须递归地执行此操作--没有循环!
(函数移位(a,i,n=a.length){
如果(n>i)a[n]=a[n-1],移位(a,i,--n);
}(a,i));
//把elt换成它的头,把尾巴放在我们打开的槽里。
a[i]=elt.shift();
a[i+1]=英语教学;
}                                                                                                     
其他的
//数组为空。
//删除该元素并将其余元素移向数组的开头。
//再次强调,必须递归地执行此操作!
(函数unshift(a,i){
如果(i

此解决方案使用ES6的位和段,例如默认函数参数和
Array.isArray
。如果您没有ES6可用,请相应地进行调整

从内到外进行递归展平。首先对找到的数组调用
flatte
函数,然后将该(现在是flat)数组的内容移动到父数组中。在数组中向后循环,这样就不必为插入的项调整循环变量

正如您所知,插入的阵列是平面的,您可以使用
splice
方法将阵列替换为其项

它的工作原理如下:

start with
[[[2, 3], 4], 5, [6, 7]]

flatten [6,7] (which is already flat) and insert:
[[[2, 3], 4], 5, 6, 7]

flatten [[2, 3], 4] recursively calls flatten [2,3] and inserts in that array:
[[2, 3, 4], 5, 6, 7]
then it inserts [2, 3, 4]:
[2, 3, 4, 5, 6, 7]
代码:

函数展平(arr){
对于(变量i=arr.length-1;i>=0;i--){
if(arr[i].构造函数===数组){
展平(arr[i]);
Array.prototype.splice.apply(arr[i,1].concat(arr[i]);
}
}
}
变量x=[[2,3,4],5,6,7];
展平(x);
//在代码段中显示结果

document.write(JSON.stringify(x))ES6:@zerkms-ES6是一件很美的事情,不是吗:p“我总是通过引用传递数组”--当你实现递归时,你应该忘记引用:你只接受和返回值。@Nate这取决于所使用的编程语言和数据结构。在JS中,递归解决方案的效率较低*.|*在大多数情况下,就地修改数据的函数使用起来很不方便:您无法组合它们。事实上,递归和就地算法之间存在一些矛盾。对于就地算法,递归在某种程度上被限制为循环的替代,而不是组合部分结果的策略。它实际上与递归无关。任何不纯函数都是不可组合的。
Array.prototype.splice.apply(arr[i,1].concat(arr[i])非常好!
start with
[[[2, 3], 4], 5, [6, 7]]

flatten [6,7] (which is already flat) and insert:
[[[2, 3], 4], 5, 6, 7]

flatten [[2, 3], 4] recursively calls flatten [2,3] and inserts in that array:
[[2, 3, 4], 5, 6, 7]
then it inserts [2, 3, 4]:
[2, 3, 4, 5, 6, 7]