Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JS array concatenation for results of recursive flattening

Good day!

Task would be to get a flat version of an array, that may include some amount of nested arrays as well as other elements. For input [1, [2], [3, [[4]]]] output [1, 2, 3, 4] expected. FreeCodeCamp spoiler alert. Naturally, recursive solution comes to mind, e.g.:

function steamrollArray(arr) {
  var result = [];
  for(var i = 0; i < arr.length; i++){
      //part of interest
      if (Array.isArray(arr[i])){
        var nestedElements = steamrollArray(arr[i]);
        for(var j = 0; j < nestedElements.length; j ++){
          result.push(nestedElements[j]);
        }
      //</part of interest>.
      } else {
        console.log("pushing: " + arr[i]);
        result.push(arr[i]);
      }
  }
  return result;
}

And it does it's thing. Result of sample run would be:

pushing: 1
pushing: 2
pushing: 3
pushing: 4
[1, 2, 3, 4]

And the question is: what goes awry, when we use concat to add nestedElements (that supposedly store return result of recursive call). If we are to change first if{} block in for loop (marked as part of interest) with snippet below:

if (Array.isArray(arr[i])){
    var nestedElements = steamrollArray(arr[i]);
    result.concat(nestedElements);
} else {

we will observe the following result:

pushing: 1
pushing: 2
pushing: 3
pushing: 4
[1]

My understanding was to pass the result of each recursive call to the concat function, which will add the returned array to the result, but for some reason it's not the case. Questions on this task was asked, like this one, but those concerned with the flattening algorithm part, which is not questioned here. I still fail to see the answer what exactly causes the difference. It very well might be something I simply overlooked in a hassle or as a result of my limited experience. Sorry if that's the case.

like image 248
shimey Avatar asked Sep 02 '16 08:09

shimey


2 Answers

Array#concat returns a new array with the result.

The concat() method returns a new array comprised of the array on which it is called joined with the array(s) and/or value(s) provided as arguments.

So you need to assign the result:

result = result.concat(nestedElements);
// ^^^^^^ assignment
like image 110
Nina Scholz Avatar answered Sep 21 '22 06:09

Nina Scholz


I am puzzled by the accepted answer as it can only concat two arrays. What you want for a nested array is actually:

var flatArray = [].concat.apply([], yourNestedArray);
like image 24
KingOfHypocrites Avatar answered Sep 20 '22 06:09

KingOfHypocrites