Search code examples
javascriptmultidimensional-arraydata-structuresdata-manipulationarray-algorithms

Iterating and searching for element in n-dimensional nested array


here is an array presented

    id: 0,
    parent: 'p1',
    children: [
        {
            id: 1,
            parent: 'p2',
            children: [
                {
                    id: 3,
                    parent: 'p4',
                    children: []
                },
            ]
        },
        {
            id: 2,
            parent: 'p3',
            children: [
                {
                    id: 4,
                    parent: 'p5',
                    children: []
                },
            ]
        }
    ]
}

I am trying to search an element based upon the id value, and remove it from the array and replace it with empty array

for example, if I pass

let childTobeReplaced = childrenCollector(4, treeData.children);

the result must be

{
    id: 0,
    parent: 'p1',
    children: [
        {
            id: 1,
            parent: 'p2',
            children: [
                {
                    id: 3,
                    parent: 'p4',
                    children: []
                },
            ]
        },
        {
            id: 2,
            parent: 'p3',
            children: []
        }
    ]
}

and childTobeReplaced must be equal to

{
    id: 4,
    parent: 'p5',
    children: []
}

The solution I implemented is as under

function childrenCollector(sourceId, nestedarray) {
    for (let index = 0; index < nestedarray.length; index++) {
        console.log(nestedarray[index].id)
        if (nestedarray[index].id === sourceId) {
            let childArray = nestedarray[index];
            nestedarray[index] = []
            return childArray;
        }
        if (nestedarray[index].children.length > 0) {
            return childrenCollector(sourceId, nestedarray[index].children);
        }else{

        }
    }
}

In this I am able to iterate through id 1 and id 3 but not able to find rest of the elements . Can someone present me with some guidance?


Solution

  • Your function will return in the first iteration of the loop when the object has children, which means that the rest of the array is not inspected. That's not what you want. Only exit the loop when you are positive that the element was found by the recursive call.

    Secondly, nestedarray[index] = [] is not removing the index from nestedarray. It merely replaces the reference to an object at that index with one to an empty array.

    Here is a possible implementation:

    function childrenCollector(sourceId, nestedArray) {
        const i = nestedArray.findIndex(({id}) => id === sourceId);
        let found;
        if (i > -1) [found] = nestedArray.splice(i, 1)
        else nestedArray.some(({children}) => 
             found = childrenCollector(sourceId, children)
        );
        return found;
    }
    
    // Example data from the question
    const treeData = {id: 0,parent: 'p1',children: [{id: 1,parent: 'p2',children: [{id: 3,parent: 'p4',children: []},]},{id: 2,parent: 'p3',children: [{id: 4,parent: 'p5',children: []},]}]};
    
    const childTobeReplaced = childrenCollector(4, treeData.children);
    console.log(childTobeReplaced);
    console.log(treeData);

    Explanation:

    With findIndex the code tries to find the id in the given array. The callback function uses destructuring to let id be the property of the iterated object. When the callback function returns true, the findIndex iteration stops, and the corresponding index is assigned to i. If there was no match, i will be set to -1.

    If there was a match, splice will extract that element from the array at that index, and will return an array of removed elements. Since there is only one removed element, that array will have just one element. This element is assigned to found, again using destructuring assignment.

    If there was no match, then the array is iterated again, but now to make the recursive calls. For this iteration some is used, which also will stop the iteration as soon as there is success. In each iteration, found is set to the result from the recursive call. As soon as this is an object (indicating something was found), the loop exits.

    In either case the found object (if any) is returned, or else undefined.