How to make a recursive method

Viewed 78

I'm trying to make a recursive method in javascript but I create an infinite loop.

My idea is create a recursive method that check that has less children that maximum value.

This is my code but as I said I dont know why create an infinite loop.

export const checkMaximumChildren = (hierarchy, maximum) => {
    let hasMoreThanMaximumChildren = false;

    if (hierarchy.children.length > maximum) {
        hasMoreThanMaximumChildren = true;
    } else {
        const dmaExtractor = (children) => {
            children.forEach((child) => {
                if (child.children.length > maximum) {
                    hasMoreThanMaximumChildren = true;
                    return hasMoreThanMaximumChildren;
                }

                if (
                    child &&
                    child.children &&
                    Array.isArray(child.children) &&
                    child.children.length > 0
                ) {
                    dmaExtractor(data.children);
                }
            });
        };

        if (
            hierarchy &&
            hierarchy.children &&
            Array.isArray(hierarchy.children) &&
            data.children.length > 0
        ) {
            dmaExtractor(hierarchy.children);
        }
    }

    return hasMoreThanMaximumChildren;
};

 const data =  [{
    "id": 1,
    "parentId": null,
    "selected": false,
    "children": [{
        "id": 2,
        "parentId": 1,
        "selected": false,
        "children": [{
            "id": 3,
            "parentId": 2,
            "selected": false,
            "children": [{
                "id": 4,
                "parentId": 3,
                "selected": false,
                "children": []
            }]
        }]
    }]
 }, {
    "id": 1,
    "parentId": null,
    "selected": true,
    "children": []
 }, {
    "id": 1,
    "parentId": null,
    "selected": true,
    "children": []
 }]

Edit

Sorry I'm stupid...

dmaExtractor(data.children); by dmaExtractor(child.children);

2 Answers

Please take a look on code below:

export const checkMaximumChildren = (hierarchy, maximum) => {
    let hasMoreThanMaximumChildren = false;

    if (hierarchy.children.length > maximum) {
        hasMoreThanMaximumChildren = true;
    } else {
        const dmaExtractor = (children) => {
            children.forEach((child) => {
                if (child.children.length > maximum) {
                    hasMoreThanMaximumChildren = true;
                    return hasMoreThanMaximumChildren;
                }

                if (
                    child &&
                    child.children &&
                    Array.isArray(child.children) &&
                    child.children.length > 0
                ) {
                    return dmaExtractor(data.children); // change #1
                }
            });
        };

        if (
            hierarchy &&
            hierarchy.children &&
            Array.isArray(hierarchy.children) &&
            data.children.length > 0
        ) {
            hasMoreThanMaximumChildren = dmaExtractor(hierarchy.children); // change #2
        }
    }

    return hasMoreThanMaximumChildren;
};

The reason behind your infinite loop was probably because internal dmaExtractor method was not returning anything.

I was testing this here, on document DOM nodes in dev console:

enter image description here

Perhaps I'm missing something important here, but why not write a recursive function to calculate the number of nodes in a hierarchy and then wrap that with a function to determine if this is no greater than the maximum?

That is:

const countKids = (data = []) => 
  data .reduce ((total, node) => total + 1 + countKids (node .children || []), 0)

const checkMaximumChildren = (hierarchy, maximum) => 
  countKids (hierarchy) <= maximum

const data = [{id: 1, parentId: null, selected: false, children: [{id: 2, parentId: 1, selected: false, children: [{id: 3, parentId: 2, selected: false, children: [{id: 4, parentId: 3, selected: false, children: []}]}]}]}, {id: 1, parentId: null, selected: true, children: []}, {id: 1, parentId: null, selected: true, children: []}]

console .log (countKids (data) )
console .log (checkMaximumChildren (data, 5))
console .log (checkMaximumChildren (data, 10))

Related