steamrollArray problem understanding

Dear all,

I have being trying to do my best in this exercise
steamroller exercise

I’ve been looking for a good response or how to implement the best way, the thing is that I found , that is very functional:


function steamrollArray(data) {
    // our initial value this time is a blank array

    const initialValue = [];
  
    // call reduce on our data
    return data.reduce((total, value) => {
      // if the value is an array then recursively call reduce
      // if the value is not an array then just concat our value
  
      return total.concat(Array.isArray(value) ? steamrollArray(value) : value);
    }, initialValue);
  }
  

console.log(steamrollArray([1, [2], [3, [[4]]]]));

I understand the reduce methods because your are going one by one, but I dont do it how it gets deeper in the different arrays.

And the last one part }, initialValue); why is this written in this way you are returning the value but why using comma.

My apologizes to everybody but I can’t understand it all then I can’t implement it for my self. If you know some resources to point out or even exercises to practice it, please let me know, I don’t want solutions, Im looking for a fishing rod.

Thanks to everybody

The beauty of it is that you want to steamroll your inner arrays as you steamroll the entire thing, if that makes sense.

array.reduce() according to MDN takes an optional initialvalue argument.

“If initialValue is not provided, reduce() will execute the callback function starting at index 1 , skipping the first index. If initialValue is provided, it will start at index 0 .”
You can read more about it in the link i have provided.

It make sense but not at all, I understand that is concatening the arrays at the same level, but when it go deeper not (apologizes english is not my mothertongue)

Let’s think about the big picture here.

I have an array. This array contains arrays. My goal is to remove everything from the sub arrays and make one simple array with all of the contents.

I want to take [1, [2], [3, [[4]]]] and turn it into [1, 2, 3, 4].

Let’s look at a way to do this without the reduce.

function steamrollArray(data) {
  // Initial array
  const newArray = [];

  // Steamroll the array
  ???!?!?!

  // Return
  return newArray;
}

In here, I am going to build a new array that contains the steamrolled version of the array.

What if I just push the contents of each sub array?

function steamrollArray(data) {
  // Initial array
  const newArray = [];

  // Steamroll the array
  for (let i = 0; i < data.length; i++) {
    let currentData = data[i];
    newArray.push(currentData);
  }

  // Return
  return newArray;
}

If we try steamrollArray([1, 2, 3, 4]) everything works ok, but we have a problem with steamrollArray([1, 2, [3], 4]).

Well, this isn’t going to work because I’m just copying the array. The elements of data might be arrays, and I really want to steamroll their contents. Lets try pulling the elements out of these sub arrays.

function steamrollArray(data) {
  // Initial array
  const newArray = [];

  // Steamroll the array
  for (let i = 0; i < data.length; i++) {
    let currentData = data[i];
    // Extract individual element if subarray
    if (Array.isArray(currentData)) {
      for (let j = 0; j < currentData.length; j++) {
        newArray.push(currentData[j]);
      }
    } else {
      newArray.push(currentData)
    }
  }

  // Return
  return newArray;
}

Well, this works for steamrollArray([1, 2, [3], 4]) but not for steamrollArray([1, 2, [3, [4]]]), and it’s ugly.

How about we steamroll the internal arrays as well?

function steamrollArray(data) {
  // Initial array
  const newArray = [];

  // If we have a single value, this is steamrolled!
  if (!Array.isArray(data))
    return [data]

  // Steamroll the array
  for (let i = 0; i < data.length; i++) {
    // Steamroll the element of the array
    let currentData = steamrollArray(data[i]);
    // Extract individual element in subarray
    for (let j = 0; j < currentData.length; j++) {
      newArray.push(currentData[j]);
    }
  }

  // Return
  return newArray;
}

Now this does exactly what we want. It isn’t fancy and elegant like the one you posted, but it gets the job done.

I hope this helped explain why those recursive calls are needed, but please let me know if I can be clearer.

Wow JeremyLT! I don’t mind if its the fanciest way to solve a problem, but you explained to me as a dumb as I am, a newie totally lost and it helps me a lot to understanding the approach to it.

Now I will try again to solve in other ways, is was being very hard the las three exercises I was doing but if I don’t effort I will not have rewards.

Thank you so so much If you were here I will give you a hug

1 Like

Only one thing left, I have been looking for how to understand.

The last part of the exercise I copied is why in the return statement this part },initialvalue) I know how works everything but If I don’t write it it doesn’t work, but you are not pushing the value or concat to it why is necesary.

Thanks to everybody.

1 Like

Have a look at reduce's syntax:

initialValue Optional

A value to use as the first argument to the first call of the callback . If no initialValue is supplied, the first element in the array will be used as the initial accumulator value and skipped as currentValue . Calling reduce() on an empty array without an initialValue will throw a TypeError .

2 Likes

Thank you very much as newere and humanities guy sometimes the most elemental scapes from my understanding.

[spoiler]` function flattener (arrContent){

var initialValue =

return arrContent.reduce((accumulator, item) => {

    return accumulator.concat(Array.isArray(item) ? flattener(item): item)

}, initialValue)  

}

console.log(flattener([1, [2], [3, [[4]]]]));
console.log(flattener([[[“a”]], [[“b”]]]))
console.log(flattener([1, {}, [3, [[4]]]]))`[/spoiler]

I had done in this way and it says it is not correct? I am doing it in visual studio and the results looks correct? any clue

What do the failing tests say?