展平嵌套数组

时间:2016-04-23 14:02:13

标签: javascript arrays

我在freeCodeCamp中制作压路机篝火 我无法弄清楚为什么我的代码无效 它只适用于数组中的第一个元素

function steamrollArray(arr) {
    // I'm a steamroller, baby


    var flat = [];

    for( i=0; i < arr.length; i++ ){
        if( Array.isArray(arr[i]) ){
           flat = flat.concat(steamrollArray(arr[i]));
        } else {
            flat.push(arr[i]);
        }
    } // end of the for loop


    return flat;
}

5 个答案:

答案 0 :(得分:0)

正如@Jonathan所评论的那样,问题在于您使用的计数器i未在函数中声明,因此是全局的。因此,递归调用将改变调用者的i等。

function steamrollArray(arr) {
    // I'm a steamroller, baby
    var flat = [];

    for(var i=0; i < arr.length; i++ ){
        if( Array.isArray(arr[i]) ){
           flat = flat.concat(steamrollArray(arr[i]));
        } else {
            flat.push(arr[i]);
        }
    } // end of the for loop
    return flat;
}

然而,第二个挑战是使代码在时间和内存上更高效。这可以通过将列表构造的数量限制为一个来完成。您可以使用名为 accumulator 的概念来执行此操作:通过递归过程更新的变量。首先,我们需要初始化变量:

function steamrollArray(arr) {
  return steamer(arr,[]);
}

在这种情况下,累加器也是结果,我们将结果初始化为空数组。显然我们仍然需要实现steamer函数:

function steamer (arr,target) {
  if(Array.isArray(arr)) {
    var n = arr.length;
    for(var i = 0; i < n; i++) {
      steamer(arr[i],target);
    }
  } else {
    target.push(arr);
  }
  return target;
}

通过数组树的递归枚举传递目标是做什么的。如果值变为标量(Array.isArray返回false),我们将元素添加到target的末尾;否则我们会执行递归调用。

此函数执行的最后一件事是返回target,在初始steamer调用之后,target将填充嵌套列表中的所有元素。

优点是我们不需要昂贵的concat函数,但只使用push函数 O(n)次。如果我们抽象构造数组所需的处理时间(假设push在O(1)时间内工作),那么算法现在可以在 O(n)时间和内存中使用< em> n 列表树中的叶子数。

答案 1 :(得分:0)

尝试使用以下方法递归数组,使用res []保存结果;

function steamrollArray(arr) {
  var res=[];
  function recurse(array)
  {
    for(var i = 0; i < array.length; i++)
    {
      if(!Array.isArray(array[i]))
        res.push(array[i]);
      else 
        recurse(array[i]);
    }
  }
  recurse(arr);
  return res;
}

答案 2 :(得分:0)

副作用,ES6,你可以使用.splice

在迭代模式中实现深度展平
function flatten(arr) {
    let i = 0;
    while (i < arr.length) {
        if (Array.isArray(arr[i])) arr.splice(i, 1, ...arr[i]);
        else ++i;
    }
    return arr;
}

e.g。使用

flatten([1, [2], [[3]], [4, [5, [6]]], [[[7], 8], 9]]);
// [1, 2, 3, 4, 5, 6, 7, 8, 9]

如果你不想要副作用,.slice之前,

functon flatClone(arr) {
    return flatten(arr.splice());
}

答案 3 :(得分:0)

function steamrollArray(arr) { 
   return String(arr).split(',').map(Number); }

如果它适用于所有情况,它适用于上面的“展平”示例,如果我错过了某些内容,请告诉我。

答案 4 :(得分:0)

这是我的代码,希望有帮助:

function steamrollArray(arr) {
  let newArr = [];

  //function:push every value in arr to newArr;
  const getValue = function(elem) {
    if(Array.isArray(elem)) {
      elem.forEach(getValue);
    }else{
      newArr.push(elem);
    }
  }

  arr.forEach(getValue);
  console.log(newArr);
  return newArr;
}

steamrollArray([[["a"]], [["b"]]]);