I have a deeply nested array like below. I want to flat the structure.
data = [
{
"id": 4321,
"name": "category1",
"parentId": null,
"children": [
{
"id": 1234,
"name": "category1",
"parentId": 4321,
"children": [
{
"id": 8327548,
"name": "001",
"parentId": 1234
},
{
"id": 8327549,
"name": "002",
"parentId": 1234
},
]
},
{
"id": 6786,
"name": "Associations",
"parentId": 4321
},
{
"id": 8262439,
"name": "category1",
"parentId": 4321
},
{
"id": 8245,
"name": "Rights",
"parentId": 4321,
"children": [
{
"id": 2447,
"name": "Organizations",
"parentId": 8245
},
{
"id": 9525,
"name": "Services",
"parentId": 8245
},
{
"id": 8448,
"name": "Organizations",
"parentId": 8245
}
]
},
{
"id": 8262446,
"name": "Women's Rights",
"parentId": 4321
}
]
},
{
"id": 21610,
"name": "Agriculture",
"parentId": null,
"children": [
{
"id": 3302,
"name": "categoryABC",
"parentId": 21610,
"children": [
{
"id": 85379,
"name": "categoryABC - General",
"parentId": 3302
},
{
"id": 85380,
"name": "categoryABC Technology",
"parentId": 3302
}
]
},
{
"id": 8303,
"name": "Fungicides",
"parentId": 21610,
"children": [
{
"id": 8503,
"name": "Fungicides - General",
"parentId": 8303
}
]
},
]
},
];
Expected output
output = [
{
"id": 8327548,
"name": "001",
"parentId": 1234
},
{
"id": 8327549,
"name": "002",
"parentId": 1234
},
...OTHER OBJECTS....
]
What I have tried so far. This is not pushing the inner children items.
function flat(array) {
var result = [];
array.forEach(function (a) {
result.push(a);
if (Array.isArray(a.children)) {
result = result.concat(flat(a.children));
}
});
return result;
}
let results = flat(data)
console.log("test", results)
Stack Snippet:
const data = [
{
"id": 4321,
"name": "category1",
"parentId": null,
"children": [
{
"id": 1234,
"name": "category1",
"parentId": 4321,
"children": [
{
"id": 8327548,
"name": "001",
"parentId": 1234
},
{
"id": 8327549,
"name": "002",
"parentId": 1234
},
]
},
{
"id": 6786,
"name": "Associations",
"parentId": 4321
},
{
"id": 8262439,
"name": "category1",
"parentId": 4321
},
{
"id": 8245,
"name": "Rights",
"parentId": 4321,
"children": [
{
"id": 2447,
"name": "Organizations",
"parentId": 8245
},
{
"id": 9525,
"name": "Services",
"parentId": 8245
},
{
"id": 8448,
"name": "Organizations",
"parentId": 8245
}
]
},
{
"id": 8262446,
"name": "Women's Rights",
"parentId": 4321
}
]
},
{
"id": 21610,
"name": "Agriculture",
"parentId": null,
"children": [
{
"id": 3302,
"name": "categoryABC",
"parentId": 21610,
"children": [
{
"id": 85379,
"name": "categoryABC - General",
"parentId": 3302
},
{
"id": 85380,
"name": "categoryABC Technology",
"parentId": 3302
}
]
},
{
"id": 8303,
"name": "Fungicides",
"parentId": 21610,
"children": [
{
"id": 8503,
"name": "Fungicides - General",
"parentId": 8303
}
]
},
]
},
];
function flat(array) {
var result = [];
array.forEach(function (a) {
result.push(a);
if (Array.isArray(a.children)) {
result = result.concat(flat(a.children));
}
});
return result;
}
let results = flat(data)
console.log("test", results)
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Can someone help me please?
CodePudding user response:
I'd suggest a recursive approach, walking through the input structure and pushing each object found to the result array.
data = [ { "id": 4321, "name": "category1", "parentId": null, "children": [ { "id": 1234, "name": "category1", "parentId": 4321, "children": [ { "id": 8327548, "name": "001", "parentId": 1234 }, { "id": 8327549, "name": "002", "parentId": 1234 }, ] }, { "id": 6786, "name": "Associations", "parentId": 4321 }, { "id": 8262439, "name": "category1", "parentId": 4321 }, { "id": 8245, "name": "Rights", "parentId": 4321, "children": [ { "id": 2447, "name": "Organizations", "parentId": 8245 }, { "id": 9525, "name": "Services", "parentId": 8245 }, { "id": 8448, "name": "Organizations", "parentId": 8245 } ] }, { "id": 8262446, "name": "Women's Rights", "parentId": 4321 } ] }, { "id": 21610, "name": "Agriculture", "parentId": null, "children": [ { "id": 3302, "name": "categoryABC", "parentId": 21610, "children": [ { "id": 85379, "name": "categoryABC - General", "parentId": 3302 }, { "id": 85380, "name": "categoryABC Technology", "parentId": 3302 } ] }, { "id": 8303, "name": "Fungicides", "parentId": 21610, "children": [ { "id": 8503, "name": "Fungicides - General", "parentId": 8303 } ] }, ] }, ];
function flat(input, result = []) {
let newObj = null;
for(let k in input) {
if (typeof(input[k]) === 'object') {
flat(input[k], result);
} else {
if (!newObj) {
newObj = {};
result.push(newObj);
}
newObj[k] = input[k];
}
}
return result;
}
console.log(flat(data))
.as-console-wrapper { max-height: 100% !important; top: 0; }
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
You need to delete a.children
from the original array:
if (Array.isArray(a.children)) {
result = result.concat(flat(a.children));
delete a.children;
}
(As @T.J.Crowde suggested, I left the snippet with a smaller array)
const data = [
{
"id": 4321,
"name": "category1",
"parentId": null,
"children": [
{
"id": 1234,
"name": "category1",
"parentId": 4321,
"children": [
{
"id": 8327548,
"name": "001",
"parentId": 1234
},
{
"id": 8327549,
"name": "002",
"parentId": 1234
},
]
},
]
},
];
function flat(array) {
var result = [];
array.forEach(function (a) {
result.push(a);
if (Array.isArray(a.children)) {
result = result.concat(flat(a.children));
delete a.children;
}
});
return result;
}
let results = flat(data)
console.log("test", results)
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>