Home > other >  Itarate over deeply nested array of objects and generate new array
Itarate over deeply nested array of objects and generate new array

Time:10-18

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:

Show code 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)

Show code 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
                    },
                ]
            },
        ]
    },
];

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>

  • Related