I been Steamrolled

I been Steamrolled
0.0 0

#1

I can’t figure this out! trying to use recursion to keep whittling away at arr, but I get RangeError: Maximum Call stack size exceeded

function steamrollArray(arr) {
  return flattenArray(arr);
}

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

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

#3

This is first time I’ve ever even heard of recursion so please bear with me.

function steamrollArray(arr) {  
  flattenArray(arr);
  return arr;
}

function flattenArray(arr) { 
  for (var i = 0; i < arr.length; i++) {
    if (Array.isArray(arr[i])) {
      arr.push(arr[i]);
      arr.shift();
      flattenArray(arr);
    } else {
      arr.push(arr[i]);
    }
  }
}

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

I was hoping that if the element was an array, I would take it’s value out and move it to the back, and keep going through until only values were left, but I get the same error.


#4

One little thing I notice is that you work directly and only with the input array, causing the Maximum call stack message. You are trying to push and shift from the same array, so it infinitely lose an index and receive one.

First thing you could do is create an empty array, and push the revelant values inside :

function steamrollArray(arr) {  
  flattenArray(arr);
  return myNewArray;
}

var myNewArray = [];

function flattenArray(arr) { 
  for (var i = 0; i < arr.length; i++) {
    if (Array.isArray(arr[i])) {
      myNewArray.push(arr[i]);
      arr.shift();
      flattenArray(arr);
    } else {
      myNewArray.push(arr[i]);
    }
  }
}

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

Keep in mind that in order to pass this challenge, you shouldn’t have any global variable (just like in my example). Figure a way to scope it inside a function, and that it retains it’s values.


#7

I feel like I’m getting close, but I’m still not sure how to shrink array:

function steamrollArray(arr) { 
  var steamrolled = [];
  
  function flattenArray(element) { 
      if (Array.isArray(element)) {
        //this needs work
        element.push(element[0]);
        element.shift();
        flattenArray(element);
      } else {
        steamrolled.push(element);
      }
  }
  
  for (var i = 0; i < arr.length; i++) {    
    flattenArray(arr[i]);
  }
  return steamrolled;
}

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

#8

It isn’t recommended to call a function inside of a for loop, I think you should do the iteration directly in flattenArray.

You still have an infinite loop in this function :

element.shift();

if element is an array, which is the case for arr[i], you are pushing first element back in arr ([[["a]]]) and then removing that same first index.

Do you really need to push anything, when it’s indeed an array and not an actual string ?


#9

So, back to this:

function steamrollArray(arr) { 
  var steamrolled = [];
  
  function flattenArray(arr) { 
    for (var i = 0; i < arr.length; i++) {
      if (Array.isArray(arr[i])) {
        arr.push(arr[i][0]);
        arr.shift();
        flattenArray(arr);
      } else {
        steamrolled.push(arr[i]);
      }
    }
  }
  
  flattenArray(arr);
  return steamrolled;
}

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

This doesn’t work either! It gives me [“a”,“b”,“b”,“b”,“b”,“b”].What I want to do is if I have [[[“a”]],[[“b”]]], I want to move [“a”] to the end and have [[[“b”]],[“a”]], and using recursion keep going down until only the value is left. This does not work! What is the best way to shrink array?


#10

You are so close :slight_smile: but please read the following : you are still pushing and shifting from the input array, and this is not necessary.

arr.push(arr[i][0]);
arr.shift();

There’s no need for that, your goal is to retrieve what’s inside theses arrays :

steamrolled.push(arr[i]);

This is done here, in your else statement. The only thing that your if statement should do, if Array.isArray(arr[i) is true is to call the same function (this is recursion) but with the next index of arr.


#11

@Mizu brilliant thanks so much! For future reference, here’s my passing code.

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

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

#12

Here is a very fast and recursive way to do this

function steamrollArray(arr) {
  if(arr && arr.constructor === Array) {
    return arr.reduce(function(acc, x) {
      return acc.concat(x && x.constructor === Array ? steamrollArray(x) : x);
    }, []);
  }
}

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