Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Concat works but push doesn't while flattening array

Following code works fine to flatten deeply nested array

const arr = [[2, [4, 9]], 6, [5,32]];;
const finalArr = [];

function flattenArr(currArr) {
  for (var el of currArr) {
    if (Array.isArray(el)) {
      finalArr.concat(flattenArr(el));
    } else {
      finalArr.push(el);
    }
  }
  return finalArr;
}
flattenArr(arr);
console.log(finalArr); // Output:[2, 4, 9, 6, 5, 32]

But if I replace concat with push, it breaks and gives the following output:

[2, 4, 9, [circular object Array], [circular object Array], 6, 5, 32, [circular object Array]]

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Can anyone help me understand why? Also, what does [circular object Array] mean?

>Solution :

First, I want to point out that the concat in your first code is effectively doing nothing. Concat creates a new array and returns that array, but you’re not using the returned array. So if you replace finalArr.concat(flattenArr(el)); with flattenArr(el); your code will still work.

const arr = [[2, [4, 9]], 6, [5,32]];
const finalArr = [];

function flattenArr(currArr) {
  for (var el of currArr) {
    if (Array.isArray(el)) {
      flattenArr(el)
    } else {
      finalArr.push(el);
    }
  }
  return finalArr;
}
flattenArr(arr);
console.log(finalArr); // Output:[2, 4, 9, 6, 5, 32]

But when you switch it to .push, push does do something. It’s going to insert into the existing finalArr array. And the thing it’s going to insert is whatever’s returned by flattenArr(el), which is finalArr. So you’re pushing the array into itself, which ends up with circular references (the array contains itself, which contains itself, which contains itself, etc), and that’s why some consoles will log it as [circular object Array].


The core issue you have is that you only ever use one array for computing the output: the array named finalArr, which you define on line 2. That is one way to solve array flattening, as your first code demonstrates. But if you prefer to do it by recursively flattening subarrays, and then combining them with push (or concat), then each time you recurse, you need to make a new array.

A second issue is that when you do the .push, you need to pass the individual items of the array as separate arguments, not the entire array as one argument. This can be done with spread syntax (...).

For example:

const arr = [[2, [4, 9]], 6, [5,32]];

function flattenArr(currArr) {
  const result = []; // Creating a brand new array
  for (var el of currArr) {
    if (Array.isArray(el)) {
      result.push(...flattenArr(el)); // Note that i used spread syntax here
    } else {
      result.push(el);
    }
  }
  return result;
}
const finalArr = flattenArr(arr);
console.log(finalArr);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading