Traverse through deeply nested arrays of objects with varying levels of child nodes

When working with a multi-node tree, adding a new row often requires obtaining the reference of that specific row by its id in order to trigger the rowclick event programmatically.

In this scenario, if a row with the id 9 needs to be added, the challenge lies in iterating through the tree structure to reach this particular node.

It's worth noting that the nesting of children nodes within other children nodes can be infinite, creating complex parent-child relationships.

Consider the following example:

let data = [{
    "id": 1,
    "name": "parent 1"
}, {
    "id": 2,
    "name": "parent 2",
    "children": [{
        "id": 5,
        "name": "parent-children 5",
    },{
        "id": 6,
        "name": "parent-children 6",
        "children": [{
            "id": 7,
            "name": "parent-children-children 7",
        },{
            "id": 8,
            "name": "parent-children-children 8",
            "children": [{
                "id": 9,
                "name": "parent-children-children-children 9",
            },{
                "id": 10,
                "name": "parent-children-children-children 10",
            }]
        }]
    }]
}, {
    "id": 3,
    "name": "parent 3"
}, {
    "id": 4,
    "name": "parent 4"
}]

To navigate through levels one and two of the nodes, you may consider implementing the following iteration function:

getItemRow(id){
    //If it is a parent node
    let myItem = this.parents.find(parent => parent.id === id);
    if(myItem !== undefined){ return myItem }

    //If it is a second-level children node (parent-children)
    this.parents.forEach(function(parent){
        let child = parent.children.find(child => child.id === id);
        if(child !== undefined){ return child }

    });
}

Answer №1

To locate a specific node, we utilize a recursive search that traverses through all nodes:

getNodeById(id){
    return findNodeWithId(id, this.parents)
}

findNodeWithId(id, rootArr) {
  for (let element of rootArr) {
    if (element.id === id) {
      return element
    }
    if (element.children) {
        const idInChild = findNodeWithId(id, element.children)
        if (idInChild !== null) {
          return idInChild
        }
    }
  }
  return null
}

Answer №2

In order to locate the object, you have two options: either directly through recursion or by searching within the children array.

const
    find = (array, id) => {
        let result;
        array.some(o => result = o.id === id
            ? o
            : find(o.children || [], id)
        )
        return result;
    },
    data = [{ id: 1, name: "parent 1" }, { id: 2, name: " parent 2", children: [{ id: 5, name: "parent-children 5" }, { id: 6, name: "parent-children 6", children: [{ id: 7, name: "parent-children-children 7" }, { id: 8, name: "parent-children-children 8", children: [{ id: 9, name: "parent-children-children-children 9" }, { id: 10, name: "parent-children-children-children 10" }] }] }] }, { id: 3, name: "parent 3" }, { id: 4, name: "parent 4" }];

console.log(find(data, 9));

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using parameters in NativeScript-Vue

I'm having trouble passing parameters to another route in Nativescript. Every time I try, it shows up as undefined. I am using the nativescript-vue-navigator. On my current screen, I have this function call: this.$navigator.navigate('/map' ...

Utilizing jQuery to Convert JSON Array Data into a Table

I am having trouble populating a table with data from a JSON array. The data is showing up in the console but I can't seem to get it into the table. Data is visible in the console screenshot below https://i.sstatic.net/C7L7d.jpg Here's what I& ...

Learn how to easily copy the success result from an Ajax call to your clipboard

Is there a way to use an ajax method to retrieve data from a controller and display it in a JQuery Dialog Box? I want to add a button within the dialog box that allows the user to easily copy the data with a single click, instead of having to manually high ...

Enhancing menu item visibility with Typescript and Vue.js 3: A step-by-step guide

How can I dynamically highlight the active menu item in my menu? I believe that adding v-if(selected) and a function might be the way to go in the first template. <template> <MenuTreeView @selected='collapsedMenuSelected' :items=&apo ...

Vue CSS is not valid - there must be at least 1 selector or at-rule

When attempting to run npm run serve in Vue, an error message is returned: Failed to compile. ./src/App.vue?vue&type=style&index=0&lang=sass& (./node_modules/css-loader/dist/cjs.js??ref--9-oneOf-1-1!./node_modules/vue-loader/lib/loaders/s ...

Combining two ng-model inputs in Angular for seamless data integration

New to Angular and seeking some guidance. I currently have two input fields, one for the area code and the other for the number. // Input field for area code <input area-input type="tel" required="true" name="area" ng-model="employee.home.area">&l ...

How do I create a clean HTML file when using the email editor with TinyMCE?

I was able to develop my own email editor, inspired by this particular example. To enhance user experience, I included a download button at the end of the file so that users can easily retrieve their edited content. The issue I'm facing is that tinym ...

Error message: "The Vuex state mapping is returning undefined values in the component

I'm currently facing an issue with a namespaced Vuex store module. I'm attempting to access the state of this module in a component using mapState to set a default value in my data. However, for some reason, the "mapped state" always comes back a ...

There is a problem with my module where multiple files that require it are overriding its variables

Currently, I am working on developing a mongo connection pool factory that is capable of checking if a connection to mongo already exists. If a connection exists, it will return that connection. However, if there is no existing connection, it will create a ...

Individual files dedicated to each controller in Angular.js are a common practice in development

In my project, I am looking to create an Angular module with a main controller, as well as additional controllers that are stored in separate files. Main module: var app = angular.module("main", []); app.controller("mainCtrl", function ($scope) { $scop ...

Implementing meta tags in React.js

I am attempting to incorporate dynamic meta-tags on each page of my website. However, despite my efforts, I cannot seem to locate the meta-tags in the page's source code. Do I need to make adjustments in public/index.html, considering that I am not ut ...

The module for the class could not be identified during the ng build process when using the --

Encountering an error when running: ng build --prod However, ng build works without any issues. Despite searching for solutions on Stack Overflow, none of them resolved the problem. Error: ng build --prod Cannot determine the module for class X! ...

Storing information within a Express application using Postgres

Recently, I've been delving into the world of Express and experimenting with a program that allows users to create events and invite others. While I know about using join tables to retrieve data, I'm curious if there's a way to organize the ...

Using Vue's forEach method in a computed property

I am currently working on a checkbox filter function that saves the value of clicked checkboxes in an array. However, I am encountering issues with updating the computed data as it is always returning undefined. The structure of the data: Casino { brand_ ...

Sending two values from an HTML form using Ajax

Looking to transfer two values from my HTML code to the PHP code: one for 'up' or 'down', and the other for the post ID. I have a system where users can vote on posts by clicking either 'up' or 'down' arrows next to ...

Ways to superimpose one div on top of another

I'm experimenting with overlaying two divs on top of a main div using CSS properties like position absolute and top. However, I'm uncertain about the correct approach to make this responsive. The Video SDK will insert the video stream into the m ...

Incorporating an array attribute into a current array of elements

I am currently attempting to incorporate the days of the week into an existing array of objects. To give you a visual representation, check out this image: https://i.stack.imgur.com/0jCBF.png After filtering my array to only yield 7 results, I aim to assi ...

const queryString = 'search=' + searchId; - using jQuery

I have recently started learning about jQuery and I am currently studying a piece of code in order to implement a similar concept in my coursework. $(function(){ $(".search").keyup(function() { var searchid = $(this).val(); var dataStr ...

What is the best way to rotate points around a mesh?

I am attempting to utilize Three.js to create a collection of points using Three.Points. My goal is to have these points rotate around a single point or mesh. I have already successfully generated the points randomly within a cylinder region, following the ...

Manipulate the curvature of a spline using three.js

In my current scene, I have a camera following a spline path. This spline is generated using the CatmullRomCurve3() method in three.js. However, there are bumps appearing automatically before and after the curve descends. I am looking to eliminate these ...