Search code examples
javascriptarraysobjectrecursionflatten

How to flatten an object that has array of objects in Javascript


I am trying to solve this question it needs me to flatten this object parent that it has children each parent has 2 children, and each child has 2 children and so on....

My goal is to flatten this to one single object.

const par = {
    id: 1,
    name: "parent",
    children: [{
        id: 2,
        name: "child 1",
        children:[{
            id: 4,
            name: "child 3",
            children: [],
        },{
            id: 5,
            name: "child 4 ",
        }]
    },{
        id: 3,
        name: "child 2",
        children: [{
            id: 6,
            name: "child 5",
        },{
            id: 7,
            name: "child 6",
            children: []
        }]
    }]
}

I tried function, but it returns an array from Deep Flatten JavaScript Object Recursively

function flat(r, a) {
    let b = {};
    Object.keys(a).forEach(function (k) {
        if (k !== 'children') {
            b[k] = a[k];
        }
    });
    r.push(b);
    if (Array.isArray(a.children)) {
        b.children = a.children.map(function (a) { return a.id;});
        return a.children.reduce(flat, r);
    }
    return r;
}


Solution

  • You still owe us a description of your desired output. But if you want something as simple as this:

    [
        {id: 1, name: "parent"},
        {id: 2, name: "child 1"},
        {id: 4, name: "child 3"},
        {id: 5, name: "child 4"},
        {id: 3, name: "child 2"},
        {id: 6, name: "child 5"},
        {id: 7, name: "child 6"}
    ]
    

    Then a depth-first recursive function can be as simple as this:

    const flatten = ({children = [], ...rest}) => [rest, ...children .flatMap (flatten)]
    
    const par = {id: 1, name: "parent", children: [{id: 2, name: "child 1", children: [{id: 4, name: "child 3", children: []}, {id: 5, name: "child 4 ", }]}, {id: 3, name: "child 2", children: [{id: 6, name: "child 5", }, {id: 7, name: "child 6", children: []}]}]}
    
    console .log (flatten (par))
    .as-console-wrapper {max-height: 100% !important; top: 0}

    If you wanted to include a parentId field, using null for root-level objects, it's only slightly more complex:

    const flatten = ({id, children = [], ...rest}, parentId = null) => [
      {id, ...rest, parentId}, ...children .flatMap (c => flatten(c, id))
    ]