Jason Djojo
Jason Djojo

Reputation: 3

Flatten a nested array

I am making the steamroller bonfire in freeCodeCamp I can't figure out why my code is not working and it only goes for the first element in an array

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

Upvotes: 0

Views: 974

Answers (5)

yz_n
yz_n

Reputation: 25

Here is my code,hope this helpful:

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

Upvotes: 0

Jen
Jen

Reputation: 352

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

If it works in all your cases, it works for the "flatten" example above, let me know if I missed something.

Upvotes: 0

Paul S.
Paul S.

Reputation: 66324

Side effects, ES6, you can achieve a deep flatten in an iterative pattern using .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. usage

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

If you don't want side effects, .slice before,

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

Upvotes: 1

孙抒涵
孙抒涵

Reputation: 11

try recurse the array in the following method, use res[] to save the result;

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

Upvotes: 0

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476594

As is commented by @Jonathan the problem is that you use a counter i which is not declared in the function and thus global. As a result recursive calls will alter the i of the caller, etc.

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

A second challenge however is making the code more efficient in both time and memory. This can be done by limiting the amount of list construction to one. You can do this by using a concept called an accumulator: a variable you update through the recursive process. First we need to initialize the variable:

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

In this case the accumulator is the result as well, and we initialize the result as an empty array. Evidently we still need to implement the steamer function:

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

What one does is passing the target through the recursive enumeration of the array tree. In case the value turns out to be a scalar (Array.isArray returns false) we add the element to the end of the target; otherwise we perform a recursive call.

The last thing this function does is returning the target, after the initial steamer call, target will be filled with all elements in the nested list.

The advantage is we do not need expensive concat functions, but only use the push function O(n) times. If we make abstraction of the processing time necessary to construct an array (assume push works in O(1) time), the algorithm now works in O(n) time and memory with n the number of leaves in the list tree.

Upvotes: 0

Related Questions