Suppose I have a nested object list like this:
[{ "id": "a", "name": "Object a", "parentId": "root", "children": [{ "id": "c", "name": "Object c" },{ "id": "d", "name": "Object D", "parentId": "a" }] }, { "id": "b", "name": "Object b", "parentId": "root" }]
The object anatomy is simple: id
, name
, children
(if any) and parentId
. I’m using this flatten function that turns the nested object
into a flat array:
function flatten(array) { var result = []; array.forEach(function (a) { result.push(a); if (Array.isArray(a.children)) { result = result.concat(flatten(a.children)); } }); return result; }
The thing is that the parentId
value is not always persistent for every object, and therefore when the object gets flattened into an array, it’s possible to lose a parent & child object relationship.
I need the flatten
method to rebuild the parentId value according to the object structure. And there’s only one catch, if the object is not a child, then it should have a parentId of root
.
Help is very much appreciated
Advertisement
Answer
If I follow correctly, you just want to flatten your structure into an array that maintains the parentId
relationship inherent in the original tree. If so, then I believe this will do:
const flatten = (xs, parentId = 'root') => xs .flatMap (({children = [], id, ...rest}) => [ {id, ...rest, parentId}, ... flatten (children, id) ]) const input = [{id: "a", name: "Object a", parentId: "root", children: [{id: "c", name: "Object c"},{id: "d", name: "Object D", parentId: "a"}]}, {id: "b", name: "Object b", parentId: "root"}] console .log (flatten (input))
.as-console-wrapper {max-height: 100% !important; top: 0}
It’s a fairly simple recursion, using flatMap
to combine the records and parameter destructuring (with default a parameter for children
) to simplify our object handling.