Building a hierarchical JSON structure from a string hierarchy

These 4 variables represent different players and their teams:

var player1 = {name:'ronaldo', team: 'europe/spain/realmadrid'}
var player2 = {name:'messi', team: 'europe/spain/barcelona'}
var player3 = {name:'gerald', team: 'europe/england/liverpool'}
var player4 = {name:'unknown english', team: 'europe/england'}

The goal is to create a JSON tree structure that organizes the information hierarchically based on region and team:

{
    "text":"europe",
    "leaf":false,
    "children":[
        {
            "text":"spain",
            "leaf":false,
            "children":[
                {
                    "text":"realmadrid",
                    "leaf":false,
                    "children":[
                        {
                            "text":"ronaldo",
                            "leaf":true
                        }
                    ]
                },
                {
                    "text":"barcelona",
                    "leaf":false,
                    "children":[
                        {
                            "text":"messi",
                            "leaf":true
                        }
                    ]
                }
            ]
        },
        {
            "text":"england",
            "leaf":false,
            "children":[
                {
                    "text":"unknown english",
                    "leaf":true
                },
                {
                    "text":"liverpool",
                    "leaf":false,
                    "children":[
                        {
                            "text":"gerald",
                            "leaf":true
                        }
                    ]
                }
            ]
        }
    ]
}

Answer №1

If el1-el4 were combined into a single object, such as:

var data = []
data[0] = {name:'ronaldo', team: 'europe/spain/realmadrid'}
data[1] = {name:'messi', team: 'europe/spain/barcelona'}
data[2] = {name:'gerald', team: 'europe/england/liverpool'}
data[3] = {name:'unknown english', team: 'europe/england'}

You could easily loop through them when processing.

It's important to consider why this needs to be stored as a JSON Tree. The structure is complex with different types of nodes - continents, countries, teams, and players. It might be more effective to convert it into a fielded structure first before generating the tree.

Edit: After further consideration, something like this might work better:

var data = [];
data[0] = {name:'ronaldo', team: 'europe/spain/realmadrid'};
data[1] = {name:'messi', team: 'europe/spain/barcelona'};
data[2] = {name:'gerald', team: 'europe/england/liverpool'};
data[3] = {name:'unknown english', team: 'europe/england'};

var tree = {};
function fillTree(name, steps) {
   let current = null;
   for (let y = 0; y < steps.length; y++) {
      if (y == 0) {
         if (!tree.children || typeof tree.children == 'undefined'){
            tree = { text: steps[y], leaf: false, children: [] };
         }
         current = tree.children;
      } else {
         current.push({ text: steps[y], leaf: false, children: [] })
         current = current[current.length - 1].children;
      }
   }
   current.push({ text: name, leaf: true })
}

for (let x = 0; x < data.length; x++) {
  steps = data[x].team.split('/');
  fillTree(data[x].name, steps)
}

This implementation creates a JavaScript object. Conversion to JSON can be done at your discretion.

Update:

A revised FillTree function that prevents duplicate entries:

var tree = {};
function fillTree(name, steps) {
   let current = null,
   existing = null,
   i = 0;
   for (let y = 0; y < steps.length; y++) {
      if (y == 0) {
         if (!tree.children || typeof tree.children == 'undefined'){
            tree = { text: steps[y], leaf: false, children: [] };
         }
         current = tree.children;
      } else {
         existing = null;
         for (i = 0; i < current.length; i++) {
            if (current[i].text === steps[y]) {
               existing = current[i];
               break;
            }
         }
         if (existing) {
            current = existing.children;
         } else {
            current.push({ text: steps[y], leaf: false, children: [] });
            current = current[current.length - 1].children;
         }
      }
   }
   current.push({ text: name, leaf: true })
}

To convert this object to JSON, you can use JSON.stringify(tree), although support may vary (JavaScript JSON Page).

Answer №2

When considering using children as object/hash instead of an array, I have come up with a solution inspired by Jordan's suggestion found at this link.

let child1 = {name:'ronaldo', team: 'europe/spain/realmadrid'}
let child2 = {name:'messi', team: 'europe/spain/barcelona'}
let child3 = {name:'gerald', team: 'europe/england/liverpool'}
let child4 = {name:'unknown english', team: 'europe/england'}

data = [child1, child2, child3, child4]
tree = {};
for(let i = 0; i < data.length; i++){
    let steps = data[i].team.split('/'); 

    steps.push(data[i].name)
    let current = tree;

    for(let j = 0; j < steps.length; j++){
        let step = steps[j]
        current.leaf = false;
        current.children = current.children || {};
        current = current.children
        current[step] = current[step] || {text: step, leaf: true} 
        current = current[step];
    }
}

Answer №3

Start by organizing your data into a flat array and then proceed to search for nested JSON structures.

For example:

[{"itemname": "item1", "settingkey": "key1", "settingvalue": "value1"}, {"itemname": "item2", "settingkey": "key2", "settingvalue": "value2"}];

Next, execute the following code snippet:


var keys = Object.keys(dataMap);

var json = [];
for (var key in keys) {
        var innerJson = {};
        innerJson["name"] = keys[key];
        var innerMap = dataMap[keys[key]];

        if (innerMap instanceof Array) {
            innerJson["size"] = innerMap[0];
        } else if (innerMap instanceof Object) {

            var child = processHierarchicalData(innerMap);
            innerJson["children"] = child;
        }
        json.push(innerJson);
}

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

methods for retrieving columns from a dictionary that lack keys

After exploring various resources on how to transform a dictionary into a data frame, I encountered an unusual format in the dictionary. It does not follow the typical pattern of key: {}, key: {} and so on.. The data consists of numerous items. However, ...

In the event that you encounter various version formats during your work

Suppose I have a number in the format Example "1.0.0.0". If I want to increase it to the next version, it would be "1.0.0.1" By using the following regex code snippet, we can achieve this perfect result of incrementing the version to "1.0.0.1": let ver ...

issue encountered during resource provider setup

Below is my code snippet where I'm attempting to populate a table using ngResource in a RESTful manner. However, when I include configuration directives, I encounter an uncaught object MINERR ASST:22 error. var app = angular.module('infra&apo ...

I am having trouble with a basic AJAX script using iframes. The first call returns a null element, but all subsequent calls work perfectly. What am I missing?

An AJAX script that performs the following sequence of actions: Creates a hidden iframe to buffer server-side output Loads PHP content silently into a div using the iframe Copies the PHP output from the server-side div to the parent page div The issue e ...

How can Codeception/Selenium help in testing the tooltip or customValidity message?

I am trying to implement a feature in my Codeception scenario where I want to validate a form submission with user errors, such as confirming a wrong email address, and display a custom tooltip message in the browser. HTML <form ... > <label ...

Angularjs directive experiencing intermittent firing of IntersectionObserver

Currently, I am in the process of integrating lazy loading using the IntersectionObserver within my angularjs application. However, there seems to be an issue where the callback function of the observer is not always being triggered when scrolling up and ...

What could be causing the three.PointLightHelper to fail in my script?

I am encountering an issue with the line of code scene.add(new THREE.PointLightHelper(bluePoint, 3)); in my code snippet below: var bluePoint = new THREE.PointLight(0x0033ff, 100, 500); bluePoint.position.set( 500, -500, 25 ); scene.addLight(bluePoint); s ...

How can I achieve a "tab selector" effect with "input" elements on a website?

I am attempting to add "tab-highlights" similar to the ones shown above the form in the screenshot to my "input" elements. This will help users know which field they are currently focused on or have clicked. I have tried using "focus" and "::selection" to ...

The AngularJs directive designed specifically for numerical values is not functioning properly in Internet Explorer 11

I've encountered an issue with an AngularJS directive that is supposed to restrict an input field to only accept numbers. Strangely, the directive functions properly in Chrome and Firefox but fails in IE11. Does anyone know what needs to be added to ...

Failure of Chrome to automatically mark checkboxes as checked upon page loading

When a user clicks on checkboxes on my page, an ajax call is made to the server with form data from the checkboxes to filter the list. However, all settings are lost when the user navigates to another page. To retain checkbox form data, I want to store it ...

CSS Element Overlapping Issue in Safari Browser

I am currently developing an audio player for my application that includes a pause/play button, next button, and back button. I have encountered a problem specifically on Safari where the back/pause buttons are overlapping each other. The play/pause button ...

Only JSON objects with a boolean value of true will be returned

I am working on returning JSON objects in JavaScript/TypeScript that have a true boolean value for the "team" property. For example, the JSON data I am using is as follows: { "state": "Texas", "stateId": 1, "team": true }, { "state": "Cali ...

looking to display the latest status value in a separate component

I am interested in monitoring when a mutation is called and updates a status. I have created a component that displays the count of database table rows when an API call is made. Below is the store I have implemented: const state = { opportunity: "" } ...

Inconsistencies observed in the behavior of Rails JavaScript assets with respect to

Currently delving into the world of Rails while also incorporating Angular into my project. Let's build a basic application from scratch. 1). Start off by creating a new Rails app: rails new hello_rails 2). Include the angular gem in your Gemfile ...

Uniqid in React fails to generate unique IDs

Currently working on creating my first react project and developing a todo list. I have incorporated the uniqid generator into my todo object, but it seems to be returning an empty id rather than a random one. Oddly enough, if I move the todo state outsi ...

Issue with Angular UI Router arises when state cannot be resolved upon page reload

I'm currently facing an issue with routing that I mentioned in the title. Even though my route is functioning, it encounters difficulties when the page is reloaded. Below is the routes object: { state: 'locations', config: { ...

Resolving Problem with Replacing Values in Pandas JSON to CSV Conversion

I'm a beginner in Python and struggling to find a solution to my query (apologies if I'm not framing it correctly). I am currently working on converting a JSON file to a CSV file. One of the columns in the file contains values enclosed within sq ...

When the icon is clicked, the text goes over the ul and the mobile slide menu goes beneath it

click here for the image Is there a way to make the text move below when I click on the hamburger menu icon? ...

Having trouble enabling push notifications on Android with ngCordova

Having trouble with push notifications through the ngCordova plugin. Followed the sample code from (with a slight change - no deviceready listener, code inside ionicPlatform.ready listener) Below is the code snippet: angular.module('myApp', [& ...

Creating a line that connects Point A to Point B using HTML, CSS, and JavaScript

Essentially, I am looking to create a line that connects point A (0vh|0vw) to point B (50vh|50vw). Initially, I considered using a div with a border and a 1px height that is rotated to achieve the desired effect. However, the issue arises when the size ...