JavaScript flattening an array of arrays of objects

JavascriptArraysLoopsFlatten

Javascript Problem Overview


I have an array which contains several arrays, each containing several objects, similar to this.

[[object1, object2],[object1],[object1,object2,object3]]

Here is a screenhot of the object logged to the console.

What would be the best approach to flattening this out so it just an array of objects?

I've tried this with no luck:

console.log(searchData);  
  var m = [].concat.apply([],searchData);    
console.log(m);

searchData logs out the screenshot above, but m logs out [ ]

Here is the actual contents of searchData:

[[{"_id":"55064111d06b96d974937a6f","title":"Generic Title","shortname":"generic-title","contents":"<p>The Healing Center offers practical, social, and spiritual support to individuals and families. Services include, but are not limited to: food and clothing, job skills training and job search assistance, auto repair (Saturdays only), mentoring, financial counseling, tutoring, prayer, life skills training, and helpful information about local community services.</p><p>Stay in touch with us:</p>","__v":0},{"_id":"5508e1405c621d4aad2d2969","title":"test english","shortname":"test-page","contents":"<h2>English Test</h2>","__v":0}],[{"_id":"550b336f33a326aaee84f883","shortname":"ok-url","title":"now english","contents":"<p>okokko</p>","category":"Transportation","__v":0}]]

Javascript Solutions


Solution 1 - Javascript

You can use Array.concat like bellow:-

var arr = [['object1', 'object2'],['object1'],['object1','object2','object3']];
var flattened = [].concat.apply([],arr);

flattened will be your expected array.

ES 2020 gives the flat, also flatMap if you want to iterate over, to flat lists of lists:

[['object1'], ['object2']].flat() // ['object1', 'object2']

Solution 2 - Javascript

A recursive solution for deep (nested) flattening:

function flatten(a) {
  return Array.isArray(a) ? [].concat.apply([], a.map(flatten)) : a;
}

A bit more compactly with ES6:

var flatten = a => Array.isArray(a) ? [].concat(...a.map(flatten)) : a;

For fun, using a generator named F for "flatten", to lazily generate flattened values:

function *F(a) {
  if (Array.isArray(a)) for (var e of a) yield *F(e); else yield a;
}

>> console.log(Array.from(F([1, [2], 3])));
<< [ 1, 2, 3 ]

For those not familiar with generators the yield * syntax yields values from another generator. Array.from takes an iterator (such as results from invoking the generator function) and turns it into an array.

Solution 3 - Javascript

If you only need simple flatten, this may works:

var arr = [['object1', 'object2'],['object1'],['object1','object2','object3']];
var flatenned = arr.reduce(function(a,b){ return a.concat(b) }, []);

For more complex flattening, Lodash has the flatten function, which maybe what you need: https://lodash.com/docs#flatten

//Syntax: _.flatten(array, [isDeep])

_.flatten([1, [2, 3, [4]]]);
// → [1, 2, 3, [4]];

// using `isDeep` to recursive flatten
_.flatten([1, [2, 3, [4]]], true);
// → [1, 2, 3, 4];

Solution 4 - Javascript

> Using ES6 Spread Operator

Array.prototype.concat(...searchData)

OR

[].concat(...searchData)

Solution 5 - Javascript

you can use flat() :

const data = [ [{id:1}, {id:2}], [{id:3}] ];
const result = data.flat();
console.log(result);

// you can specify the depth

const data2 = [ [ [ {id:1} ], {id:2}], [{id:3}] ];
const result2 = data2.flat(2);

console.log(result2);

in your case :

const data = [[{"_id":"55064111d06b96d974937a6f","title":"Generic Title","shortname":"generic-title","contents":"<p>The Healing Center offers practical, social, and spiritual support to individuals and families. Services include, but are not limited to: food and clothing, job skills training and job search assistance, auto repair (Saturdays only), mentoring, financial counseling, tutoring, prayer, life skills training, and helpful information about local community services.</p><p>Stay in touch with us:</p>","__v":0},{"_id":"5508e1405c621d4aad2d2969","title":"test english","shortname":"test-page","contents":"<h2>English Test</h2>","__v":0}],[{"_id":"550b336f33a326aaee84f883","shortname":"ok-url","title":"now english","contents":"<p>okokko</p>","category":"Transportation","__v":0}]]

const result = data.flat();

console.log(result);

Solution 6 - Javascript

I've noticed that people are using recursions which are not cost friendly, especially with new ES6 standards giving us the power of spread operators. When you're pushing the items into the master array just use ... and it will automatically add flattened objects. Something like

array.push(...subarray1)    // subarray1 = [object1, object2]
array.push(...subarray2)    // subarray2 = [object3]
array.push(...subarray3)    // subarray3 = [object4,object5, object6]
// output -> array = [object1, object2, object3, object4, object5, object6]

Solution 7 - Javascript

Recursively flatten an array:

function flatten(array) {
   return !Array.isArray(array) ? array : [].concat.apply([], array.map(flatten));
}

var yourFlattenedArray = flatten([[{"_id":"55064111d06b96d974937a6f","title":"Generic Title","shortname":"generic-title","contents":"<p>The Healing Center offers practical, social, and spiritual support to individuals and families. Services include, but are not limited to: food and clothing, job skills training and job search assistance, auto repair (Saturdays only), mentoring, financial counseling, tutoring, prayer, life skills training, and helpful information about local community services.</p><p>Stay in touch with us:</p>","__v":0},{"_id":"5508e1405c621d4aad2d2969","title":"test english","shortname":"test-page","contents":"<h2>English Test</h2>","__v":0}],[{"_id":"550b336f33a326aaee84f883","shortname":"ok-url","title":"now english","contents":"<p>okokko</p>","category":"Transportation","__v":0}]]

);

log(yourFlattenedArray);

function log(data) { document.write('

' + JSON.stringify(data, null, 2) + '

'); }

  • {font-size: 12px; }

Solution 8 - Javascript

let functional = {
	flatten (array) {
		if (Array.isArray(array)) {
			return Array.prototype.concat(...array.map(this.flatten, this));
		}

		return array;
	}
};

functional.flatten([0, [1, 2], [[3, [4]]]]); // 0, 1, 2, 3, 4

Solution 9 - Javascript

My solution to flatten an array of objects and return a single array.

flattenArrayOfObject = (arr) => {
  const flattened = {};

  arr.forEach((obj) => {
    Object.keys(obj).forEach((key) => {
      flattened[key] = obj[key];
    });
  });

  return flattened;
};

Example

const arr = [  {    verify: { '0': 'xyzNot verified', '1': 'xyzVerified' },    role_id: { '1': 'xyzMember', '2': 'xyzAdmin' },    two_factor_authentication: { '0': 'No', '1': 'Yes' }  },  { status: { '0': 'xyzInactive', '1': 'Active', '2': 'xyzSuspend' } }]

flattenArrayOfObject(arr)

// {
//   verify: { '0': 'xyzNot verified', '1': 'xyzVerified' },
//   status: { '0': 'xyzInactive', '1': 'Active', '2': 'xyzSuspend' },
//   role_id: { '1': 'xyzMember', '2': 'xyzAdmin' },
//   two_factor_authentication: { '0': 'No', '1': 'Yes' }
// }

Solution 10 - Javascript

You can use this custom recursive method to flattened any nested array

const arr = [
  [1, 2],
  [3, 4, 5],
  [6, [7, 8], 9],
  [10, 11, 12]
]

const flatenedArray = arr => {
  let result = [];
  if(!arr.constructor === Array) return;
  arr.forEach(a => {
  	if(a.constructor === Array) return result.push(...flatenedArray(a));
  	result.push(a);
  });
  return result;
}


console.log(flatenedArray(arr)); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

Solution 11 - Javascript

If each object has an array and continues in the same way nested :

function flatten(i,arrayField){
  if(Array.isArray(i)) return i.map(c=>flatten(c,arrayField));
  if(i.hasOwnProperty(arrayField)) return [{...i,[arrayField]:null},...i[arrayField].map(c=>flatten(c,arrayField))];
  return {...i,[arrayField]:null};
}

let data=flatten(myData,'childs');

mydata like this :

[{    "id": 1,    "title": "t1",    "sort_order": 200,    "childs": [        {            "id": 2,            "title": "t2",            "sort_order": 200,            "childs": []
        },
        {
            "id": 3,
            "title":"mytitle",
            "sort_order": 200,
            "childs": []
        },
        {
            "id": 4,
            "title":"mytitle",
            "sort_order": 200,
            "childs": []
        },
        {
            "id": 5,
            "title":"mytitle",
            "sort_order": 200,
            "childs": []
        },
        {
            "id": 6,
            "title":"mytitle",
            "sort_order": 200,
            "childs": []
        }
    ]
},
{
    "id": 7,
    "title": "راهنما",
    "sort_order":"mytitle",
    "childs": [
        {
            "id": 8,
            "title":"mytitle",
            "sort_order": 200,
            "childs": []
        },
        {
            "id": 9,
            "title":"mytitle",
            "sort_order": 200,
            "childs": []
        },
        {
            "id": 10,
            "title":"mytitle",
            "sort_order": 200,
            "childs": []
        }
    ]
}

]

Solution 12 - Javascript

let nestedArray = [[1, 2], [3, 4], [5, 6]];

let flattenArray = function(nestedArray) {

	let flattenArr = [];
  
	nestedArray.forEach(function(item) {
  	flattenArr.push(...item);
  });
  
  return flattenArr;
};

console.log(flattenArray(nestedArray)); // [1, 2, 3, 4, 5, 6]

Solution 13 - Javascript

var arr = [1,[9,22],[[3]]];
var res = [];

function flatten(arr){
for(let i=0;i<arr.length;i++){
if(typeof arr[i] == "number"){
res.push(arr[i]);
}
else if(typeof arr[i] == "object"){
fatten(arr[i]);
}
}
}

Calling function

flatten(arr);
console.log(res);

Result  

[1, 9, 22, 3]

Solution 14 - Javascript

// Polyfill flat method

var flatten = a => Array.isArray(a) ? [].concat(...a.map(flatten)) : a;

var deepFlatten = (arr, depth = 1) => {
   return depth > 0 ? arr.reduce((acc, val) => acc.concat(Array.isArray(val) ? deepFlatten(val, depth - 1) : val), [])
                : arr.slice();
}

console.log(deepFlatten([0, 1, 2, [[[3, 4]]]], Infinity));

// You can pass label in place of 'Infinity'

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionbyrdrView Question on Stackoverflow
Solution 1 - JavascriptMritunjayView Answer on Stackoverflow
Solution 2 - Javascriptuser663031View Answer on Stackoverflow
Solution 3 - JavascriptHuy Hoang PhamView Answer on Stackoverflow
Solution 4 - JavascriptShreyasView Answer on Stackoverflow
Solution 5 - JavascriptTakiView Answer on Stackoverflow
Solution 6 - JavascriptAdnan KhanView Answer on Stackoverflow
Solution 7 - JavascriptMiguel MotaView Answer on Stackoverflow
Solution 8 - JavascriptAlexander AbashkinView Answer on Stackoverflow
Solution 9 - JavascriptU.AView Answer on Stackoverflow
Solution 10 - JavascriptPrabu ReddyView Answer on Stackoverflow
Solution 11 - JavascriptMohammad DaneshamoozView Answer on Stackoverflow
Solution 12 - JavascriptTarun MajumderView Answer on Stackoverflow
Solution 13 - JavascriptGajender SinghView Answer on Stackoverflow
Solution 14 - JavascriptRohitView Answer on Stackoverflow