Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deep Flatten JavaScript Object Recursively

Tags:

Data:

var data = [     {       "id": 1,       "level": "1",       "text": "Sammy",       "type": "Item",       "items": [         {           "id": 11,           "level": "2",           "text": "Table",           "type": "Item",           "items": [             {               "id": 111,               "level": "3",               "text": "Dog",               "type": "Item",               "items": null             },             {               "id": 112,               "level": "3",               "text": "Cat",               "type": "Item",               "items": null             }           ]         },         {           "id": 12,           "level": "2",           "text": "Chair",           "type": "Item",           "items": [             {               "id": 121,               "level": "3",               "text": "Dog",               "type": "Item",               "items": null             },             {               "id": 122,               "level": "3",               "text": "Cat",               "type": "Item",               "items": null             }           ]         }       ]     },     {       "id": 2,       "level": "1",       "text": "Sundy",       "type": "Item",       "items": [         {           "id": 21,           "level": "2",           "text": "MTable",           "type": "Item",           "items": [             {               "id": 211,               "level": "3",               "text": "MTDog",               "type": "Item",               "items": null             },             {               "id": 212,               "level": "3",               "text": "MTCat",               "type": "Item",               "items": null             }           ]         },         {           "id": 22,           "level": "2",           "text": "MChair",           "type": "Item",           "items": [             {               "id": 221,               "level": "3",               "text": "MCDog",               "type": "Item",               "items": null             },             {               "id": 222,               "level": "3",               "text": "MCCat",               "type": "Item",               "items": null             }           ]         }       ]     },     {       "id": 3,       "level": "1",       "text": "Bruce",       "type": "Folder",       "items": [         {           "id": 31,           "level": "2",           "text": "BTable",           "type": "Item",           "items": [             {               "id": 311,               "level": "3",               "text": "BTDog",               "type": "Item",               "items": null             },             {               "id": 312,               "level": "3",               "text": "BTCat",               "type": "Item",               "items": null             }           ]         },         {           "id": 32,           "level": "2",           "text": "Chair",           "type": "Item",           "items": [             {               "id": 321,               "level": "3",               "text": "BCDog",               "type": "Item",               "items": null             },             {               "id": 322,               "level": "3",               "text": "BCCat",               "type": "Item",               "items": null             }           ]         }       ]     }   ]; 

Code:

var fdr = []; var fd = function(n) {   if (n.items) {     _.forEach(n.items, function (value){       fd(value);     });   }    fdr.push(n); }; _.forEach(data, fd); console.log(fdr); 

Desired output:

var data = [     {       "id": 1,       "level": "1",       "text": "Sammy",       "type": "Item",       "items": []     },     {       "id": 11,       "level": "2",       "text": "Table",       "type": "Item",       "items": []     },     {       "id": 111,       "level": "3",       "text": "Dog",       "type": "Item",       "items": null     },     {       "id": 112,       "level": "3",       "text": "Cat",       "type": "Item",       "items": null     },     {       "id": 12,       "level": "2",       "text": "Chair",       "type": "Item",       "items": []     },     {       "id": 121,       "level": "3",       "text": "Dog",       "type": "Item",       "items": null     },     {       "id": 122,       "level": "3",       "text": "Cat",       "type": "Item",       "items": null     },     {       "id": 2,       "level": "1",       "text": "Sundy",       "type": "Item",       "items": []     },     {       "id": 21,       "level": "2",       "text": "MTable",       "type": "Item",       "items": []     },     {       "id": 211,       "level": "3",       "text": "MTDog",       "type": "Item",       "items": null     },     {       "id": 212,       "level": "3",       "text": "MTCat",       "type": "Item",       "items": null     },     {       "id": 22,       "level": "2",       "text": "MChair",       "type": "Item",       "items": []     },     {       "id": 221,       "level": "3",       "text": "MCDog",       "type": "Item",       "items": null     },     {       "id": 222,       "level": "3",       "text": "MCCat",       "type": "Item",       "items": null     },     {       "id": 3,       "level": "1",       "text": "Bruce",       "type": "Folder",       "items": []     },     {       "id": 31,       "level": "2",       "text": "BTable",       "type": "Item",       "items": []     },     {       "id": 311,       "level": "3",       "text": "BTDog",       "type": "Item",       "items": null     },     {       "id": 312,       "level": "3",       "text": "BTCat",       "type": "Item",       "items": null     },     {       "id": 32,       "level": "2",       "text": "Chair",       "type": "Item",       "items": []     },     {       "id": 321,       "level": "3",       "text": "BCDog",       "type": "Item",       "items": null     },     {       "id": 322,       "level": "3",       "text": "BCCat",       "type": "Item",       "items": null     }   ]; 

Conditions:

  • Object have unknowns level. Some child item may have one level down and some could have up to 5.

Questions

The fd function in the code is what I have come up with. I believe there's a 'cleaner' way to do this, just can't think of something. Plus, the function return items object, render it circular object.

JsBin: http://jsbin.com/debojiqove/2/edit?html,js,output

Is there a way to flatten object recursively with lodash or just plain JavaScript?.

like image 301
stack247 Avatar asked Apr 22 '16 20:04

stack247


2 Answers

A solution in plain Javascript with respect to the items. It does not mutate the source array.

function flat(r, a) {     var b = {};     Object.keys(a).forEach(function (k) {         if (k !== 'items') {             b[k] = a[k];         }     });     r.push(b);     if (Array.isArray(a.items)) {         b.items = a.items.map(function (a) { return a.id; });         return a.items.reduce(flat, r);     }     return r; }  var data = [{ "id": 1, "level": "1", "text": "Sammy", "type": "Item", "items": [{ "id": 11, "level": "2", "text": "Table", "type": "Item", "items": [{ "id": 111, "level": "3", "text": "Dog", "type": "Item", "items": null }, { "id": 112, "level": "3", "text": "Cat", "type": "Item", "items": null }] }, { "id": 12, "level": "2", "text": "Chair", "type": "Item", "items": [{ "id": 121, "level": "3", "text": "Dog", "type": "Item", "items": null }, { "id": 122, "level": "3", "text": "Cat", "type": "Item", "items": null }] }] }, { "id": 2, "level": "1", "text": "Sundy", "type": "Item", "items": [{ "id": 21, "level": "2", "text": "MTable", "type": "Item", "items": [{ "id": 211, "level": "3", "text": "MTDog", "type": "Item", "items": null }, { "id": 212, "level": "3", "text": "MTCat", "type": "Item", "items": null }] }, { "id": 22, "level": "2", "text": "MChair", "type": "Item", "items": [{ "id": 221, "level": "3", "text": "MCDog", "type": "Item", "items": null }, { "id": 222, "level": "3", "text": "MCCat", "type": "Item", "items": null }] }] }, { "id": 3, "level": "1", "text": "Bruce", "type": "Folder", "items": [{ "id": 31, "level": "2", "text": "BTable", "type": "Item", "items": [{ "id": 311, "level": "3", "text": "BTDog", "type": "Item", "items": null }, { "id": 312, "level": "3", "text": "BTCat", "type": "Item", "items": null }] }, { "id": 32, "level": "2", "text": "Chair", "type": "Item", "items": [{ "id": 321, "level": "3", "text": "BCDog", "type": "Item", "items": null }, { "id": 322, "level": "3", "text": "BCCat", "type": "Item", "items": null }] }] }];  document.write('<pre>' + JSON.stringify(data.reduce(flat, []), 0, 4) + '</pre>');
like image 172
Nina Scholz Avatar answered Sep 21 '22 02:09

Nina Scholz


With a bit of ES6 flavor

function flatten(xs) {   return xs.reduce((acc, x) => {     acc = acc.concat(x);     if (x.items) {       acc = acc.concat(flatten(x.items));       x.items = [];     }     return acc;   }, []); } 
like image 30
Роман Парадеев Avatar answered Sep 23 '22 02:09

Роман Парадеев