0

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)

Can someone help me please?

3
  • 2
    You only need to include a few children in the example, not all of them. Commented Oct 18, 2021 at 6:49
  • No, all the children elements need to be added, if the children element is having other children elements those needs to be added as well Commented Oct 18, 2021 at 6:51
  • 3
    That's not what I meant. I meant the example in the question doesn't have to have hundreds of child objects in it, and having them makes it really hard to work with when trying to help you. I've chopped it down markedly and copied your code into a stack snippet. Which children, specifically, do you think are missing from your result? What you have looks fine to me. concat is never my first choice, but it should be fine. "This is not pushing the inner children items" For instance, I'm seeing child id=8327548 in the result. Commented Oct 18, 2021 at 6:53

2 Answers 2

2

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; }

Sign up to request clarification or add additional context in comments.

Comments

1

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.