Determine the total number of nested objects within a JSON structure using Javascript

Consider the JSON structure below:

{
  "id": "foo",
  "list": [
    {
      "id": "A",
      "list": [
        {
          "id": "B",
          "list": [
            {
              "id": "C",
              "list": [
                {
                  "id": "D",
                  "list": []
                },
                {
                  "id": "E",
                  "list": []
                }
              ]
            },
            {
              "id": "F",
              "list": []
            },
            {
              "id": "G",
              "list": [
                {
                  "id": "H",
                  "list": []
                },
                {
                  "id": "I",
                  "list": []
                },
                {
                  "id": "J",
                  "list": []
                }
              ]
            }
          ]
        },
        {
          "id": "K",
          "list": []
        }
      ]
    },
    {
      "id": "L",
      "list": [
        {
          "id": "M",
          "list": []
        }
      ]
    },
    {
      "id": "N",
      "list": []
    },
    {
      "id": "O",
      "list": [
        {
          "id": "P",
          "list": [
            {
              "id": "Q",
              "list": []
            },
            {
              "id": "R",
              "list": []
            },
            {
              "id": "S",
              "list": []
            },
            {
              "id": "T",
              "list": [
                {
                  "id": "U",
                  "list": []
                }
              ]
            },
            {
              "id": "V",
              "list": [
                {
                  "id": "W",
                  "list": [
                    {
                      "id": "X",
                      "list": []
                    },
                    {
                      "id": "Y",
                      "list": []
                    },
                    {
                      "id": "Z",
                      "list": []
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

Your task is to count each child node and add this count as a property to each object.

For instance:

  • The "C" object has 2 child nodes, "D" and "E".
  • The "W" object has 3 child nodes, "X", "Y", and "Z".
  • The "V" object has 4 child nodes, including its own children ("W" and the three aforementioned).

To achieve this, each object should have a property, let's call it "allBelow", that contains the count of its child nodes. All objects need to be processed in this manner.

You may need to implement a recursive function for this task, as grouping nested child elements might require additional logic.

If you encounter any challenges with this, feel free to reach out for assistance.

Best regards,

Answer №1

var newObject = {"id":"foo","list":[{"id":"A","list":[{"id":"B","list":[{"id":"C","list":[{"id":"D","list":[]},{"id":"E","list":[]}]},{"id":"F","list":[]},{"id":"G","list":[{"id":"H","list":[]},{"id":"I","list":[]},{"id":"J","list":[]}]}]},{"id":"K","list":[]}]},{"id":"L","list":[{"id":"M","list":[]}]},{"id":"N","list":[]},{"id":"O","list":[{"id":"P","list":[{"id":"Q","list":[]},{"id":"R","list":[]},{"id":"S","list":[]},{"id":"T","list":[{"id":"U","list":[]}]},{"id":"V","list":[{"id":"W","list":[{"id":"X","list":[]},{"id":"Y","list":[]},{"id":"Z","list":[]}]}]}]}]}]};
 
function calculateItems(obj) {
  var count = obj.list.length;
  count += obj.list.reduce((a, e) => a + calculateItems(e), 0);
  obj.count = count; // assign the count after calculating the subobjects.
  return count; // return the calculated count to be used by parent objects
}
 
calculateItems(newObject);
 
console.log(newObject);

Answer №2

Here's a straightforward approach using Depth First Search (DFS):

function countTotalChildren(currentNode) {  
  const numChildren = currentNode.list.reduce((acc, node) => {
    return acc + countTotalChildren(node);
  }, 0)

  currentNode.allDescendants = numChildren;

  return numChildren + 1;
}

countTotalChildren(treeData);

https://jsfiddle.net/hyq37geL/

Answer №3

To solve this problem, I suggest using a depth-first search algorithm similar to the one below (Note: code is untested):

function performDFS(tree){
    var totalCount = tree.items.length;
    for(var j=0; j<totalCount; j++){
        totalCount += performDFS(tree.items[j]);
    }
    tree["total"] = totalCount;
    return totalCount;
}

Answer №4

If you're looking for a powerful algorithm, consider using a recursive function like the one below:

var data = {"id":"foo","list":[{"id":"A","list":[{"id":"B","list":[{"id":"C","list":[{"id":"D","list":[]},{"id":"E","list":[]}]},{"id":"F","list":[]},{"id":"G","list":[{"id":"H","list":[]},{"id":"I","list":[]},{"id":"J","list":[]}]}]},{"id":"K","list":[]}]},{"id":"L","list":[{"id":"M","list":[]}]},{"id":"N","list":[]},{"id":"O","list":[{"id":"P","list":[{"id":"Q","list":[]},{"id":"R","list":[]},{"id":"S","list":[]},{"id":"T","list":[{"id":"U","list":[]}]},{"id":"V","list":[{"id":"W","list":[{"id":"X","list":[]},{"id":"Y","list":[]},{"id":"Z","list":[]}]}]}]}]}]};

function addCount(node) {
  node.count = 0;
  for (var i = 0; i < node.list.length; i++) {
    var child = node.list[i];
    addCount(child);
    node.count += child.count + 1;
  }
}

addCount(data);
console.log(data)

This function recursively calls itself on each child node and calculates the count by including the number of grandchildren as well.

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

Shade the entire td column in different colors depending on the characteristics of th

I am working with a table and here is the code for it: <table> <thead> <tr> <th style="width: 40%; text-align: center; vertical-align: center;">Nr.<br> crt.</th> <th style="font-weight: bold; wi ...

Is there a way to prevent users from copying data or switching tasks when using my program or website?

Is it feasible to develop a website or application for Windows desktop machines that can remain focused until the user completes a specific task? For instance, if my YYY app/website is open and I require the user to input some text, I want to restrict the ...

Generate JSON Data from Comma-Separated Values

I have a CSV file containing the following data. Check out the image for reference. I'm working with pandas in Python. My goal is to convert this data into JSON format structured like this: { "VMName": "vm101", ...

What is the best way to handle responses in axios when dealing with APIs that stream data using Server-Sent Events (S

Environment: web browser, javascript. I am looking to utilize the post method to interact with a Server-Send Events (SSE) API such as: curl https://api.openai.com/v1/completions \ -H "Content-Type: application/json" \ -H ...

What is the best way to position the left sidebar on top of the other components and shift them to the

Currently, I am working on a project to display NBA data fetched from an API. I am aiming to recreate the design showcased here: Dribbble Design My main challenge lies in overlaying the left sidebar onto the main box and shifting the components sligh ...

Automatically retrieve the generated PDF file upon completion (Node.js and Express)

I've been utilizing the node module html-pdf to seamlessly convert my HTML into PDF format. The conversion process goes smoothly, but I'm encountering difficulties when it comes to downloading the file once it's been generated. Below is the ...

When attempting to pass data to another page by clicking on a row, the result is that the data appears to be empty

I have been using the MUI-Datatable component, which is able to navigate to the next page. However, when I try to view the data on the History page, nothing appears. How can I resolve this issue? Data transfer to another page: Even though I can see the d ...

What is the proper way to connect an external Javascript file to an html document within a Play Framework project?

Below is the content of my scala.html file: @() <!DOCTYPE html> <html> <head> <title> Spin To Win </title> <link rel="stylesheet" media="screen" href="@routes.Assets.versioned("stylesheets/styles.css")" ...

I noticed that my jquery code is injecting extra white space into my HTML5 video

Ensuring my HTML5 background video stays centred, full-screen, and aligned properly has been made possible with this jQuery snippet. $(document).ready(function() { var $win = $(window), $video = $('#full-video'), $videoWrapper = $video. ...

Is there a way to upload multiple files using expressjs?

I'm looking for a way to efficiently send multiple files, including an entire directory, so that I can access them in another JavaScript file called from an HTML file. const app = require("express")(); const http = require("http"). ...

Using various hues for segmented lines on ChartJS

I am working with a time line chart type and I want to assign colors to each step between two dots based on the values in my dataset object. In my dataset data array, I have added a third item that will determine the color (if < 30 ==> green / >30 ==> red ...

Having trouble triggering a click event with JQuery

I have a hidden link for downloading Audio Files that I want the user to access using a button. However, I am having trouble triggering the click event. Below is the HTML code: <a class="APopupDown" data-icon="home" id="DownloadFile" href="http://yaho ...

Creating dynamic child components in Vue.js version 2

I am currently developing a facet search system using VueJS. The concept is fairly straightforward: Within a FilterGroup component lies the overarching filter logic. This component allows for several child components, such as AttributeXYZFilter, to provid ...

I am experiencing difficulty in detecting variable changes within my $scope function

I'm encountering an issue where a variable isn't being updated in a $scope function when there's a state change event. Despite seeing the variable update in the event listener, it doesn't reflect in the function. The code snippet in qu ...

loading dynamic content into an appended div in HTML using Angular

Here is the HTML code from my app.component.html file: <button mat-raised-button color="primary" mat-button class="nextButton" (click)="calculatePremium()"> Calculate </button> <div id="calcul ...

Error message: Vue warning - The prop "disabled" must be a boolean type, but a function was provided instead

I have this code snippet that I am currently using <v-list-item> <v-btn @click="onDownloadFile(document)" :disabled=getFileExtention >Download as pdf</v-btn > < ...

How to show a placeholder in a select input using ReactJS

I'm currently trying to incorporate placeholder text into a select input field using ReactJS, but it doesn't seem to be working as intended. Here is the code snippet I am working with: <Input type="select" placeholder="placeholder"> ...

The React/Redux application is experiencing difficulties with API calls, as they are returning empty responses and the actions are not being triggered

Hey there, I'm currently working on a React Native app and running into some issues with making API get requests. It seems like the response is throwing an error and the action isn't executing properly. I'll share my code below, so if anyone ...

The removal of an object becomes unsuccessful when objects with lower indices have been deleted beforehand

Attempting to construct a multi-layer object representing a program; check out my progress here http://codepen.io/Irish1/pen/lbjdw Imagine adding 3 weeks, each with 3 days, and each day having 3 sessions. Removing these objects is feasible as long as caut ...

Encountering a php error when decoding multiple JSON files due to an unexpected end of file

Hey there! I'm currently working on a project where I need to load JSON files from a specific folder and then decode them to populate a database. Below is the code snippet I am using for this task: <?php $con = mysqli_connect("localhost", "root", ...