I am in search of a way to utilize JavaScript in order to transform a "flat" JSON object into a nested JSON tree that allows for a one-to-many matching capability

I'm on a mission to transform a flat JSON object into a nested tree using JavaScript. The unique challenge I'm facing is the need to match one child node to multiple parent nodes, a scenario I haven't found in existing solutions.

Behold, my flat JSON object:

[{
    id: 200,
    title: "child with 2 parents",
    parent_ids: [1, 2]
}, {
    id: 202,
    title: "child with 1 parent",
    parent_ids: [1]
}, {
    id: 1,
    title: "parent 1",
    children: []
}, {
    id: 2,
    title: "parent 2",
    children: []
}]

I'm aware I could potentially loop through parents and children separately to pair them up, but that approach seems inefficient. I'm curious to explore if there's a more efficient method to achieve this.

Here's the desired outcome:

Observe how the child with 2 parents is linked to both parents seamlessly.

[
   {
    id: 1,
    title: "parent 1",
    children: [{
        id: 200,
        title: "child with 2 parents",
        parent_ids: [1, 2]
    }, {
        id: 202,
        title: "child with 1 parent",
        parent_ids: [1]
    }]
   },
   {
    id: 2,
    title: "parent 2",
    children: [{
        id: 200,
        title: "child with 2 parents",
        parent_ids: [1, 2]
    }]
   }
]

Answer №1

To obtain a result set containing all nodes without parents, you can store all nodes in a hash table and identify those without parents.

function getTree(data) {
    var temp = {},
        parents = [];

    data.forEach(o => {
        o.children = temp[o.id] && temp[o.id].children;
        temp[o.id] = o;
        if (!o.parent_ids) {
            parents.push(o.id);
            return;
        }
        o.parent_ids.forEach(id => {
            temp[id] = temp[id] || {};
            temp[id].children = temp[id].children || [];
            temp[id].children.push(o);
        });
    });
    return parents.map(id => temp[id]);
}

var data = [{ id: 200, title: "child with 2 parents", parent_ids: [1, 2] }, { id: 202, title: "child with 1 parent", parent_ids: [1] }, { id: 1, title: "parent 1", children: [] }, { id: 2, title: "parent 2", children: [] }],
    tree = getTree(data);

console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }

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

"Unsuccessful jSON request made by Ajax resulting in undefined response

I've implemented an ajax call to fetch data from a json file and display it in an HTML table. Everything was working fine initially, but now it seems to be returning UNDEFINED. Could it be that the data from the json file hasn't finished loading ...

I notice a discrepancy with the IndexOutOfBoundsException

After obtaining JSON data, I wanted to display the information in my listView. To achieve this, I parsed the data into an ArrayList<String> and then added it to the adapter. { "areas": [ { "fieldTag": "1", "areaId": 2, "areaN ...

Issue encountered while executing tasks in the Gruntfile.js file

Having trouble with Grunt concatenating my CSS files into one named production.css Below is the output I received from the command prompt: C:\Users\josha\Desktop\Repos\AJAX Project - Grunt Test>grunt C:\Users\josha& ...

My goal is to have the "show more" button reveal extra information without having to reload the entire page

I’m trying to figure out how to make the “more” button show additional information without reloading the entire page. I’ve done some research online and found that AJAX can help with this, but since I’m just starting to learn JavaScript, I have n ...

Organize elements with jQuery, remove, detach, clone, and append without worrying about memory leaks

I am facing a challenge with a parent div that contains approximately 300 child divs, each one containing an image and some text. I have an array with the necessary information to reorder these divs using references. However, whenever I loop through the a ...

Inserting a file read using Node.js into a MongoDB database

Recently, I came across a text file that contains the following data: title: A, alert: notice, desc: Starting title: B, alert: notice, desc: Process Step 1 and 2 Step 1 - Execute Step 2 - Log title: C, alert: notice, desc: "Ending" My goal is to insert ...

The button text in Bootstrap 5 is black instead of white as shown in their demo

During the installation of Bootstrap 5, I encountered an issue where many of my buttons are displaying a black font instead of the expected white font as shown in the Bootstrap 5 Documentation For instance, the .btn-primary button on the official Bootstra ...

What is the memory allocation for null values in arrays by node.js?

Continuing the discussion from this thread: Do lots of null values in an array pose any harm? I experimented with node.js by doing this: arr=[] arr[1000]=1 arr[1000000000]=2 arr.sort() However, I encountered the following error: FATAL ERROR: JS Alloca ...

Embarking on a journey to master the art of JSON

I'm looking to master the process of extracting data from .json files using the Weather Underground API. I've made some progress, but my current script displays the highs and lows for each day. How can I modify it to only show today's high a ...

Wrapping a group of elements with opening and closing tags using jQuery

I have a collection of distinct elements, like so: <section class="box-1"></section> <section class="box-2"></section> <section class="box-3"></section> My objective is to enclose all three elements within a div with a ...

What is the best way to generate a new component by triggering an event with Vue.js?

Imagine you have a list of posts retrieved from an ajax response, and now you want to provide users with the option to edit any specific post by clicking a button. One approach could be using the v-show directive to attach a form component to each post. Wh ...

A collection of asynchronous requests stemming from a sole request

I am facing a unique ajax scenario that is proving to be quite challenging for me. Here is the specific sequence of events that I need to coordinate: An initial request returns an array of ID numbers. A separate request needs to be sent for each ID in ...

An effective way to utilize the h() function in Vuejs to render a component instance

I'm currently working on a Vuejs component setup that resembles the following structure: <template> <button @click="generateItem()">Add item</button> <div class="container"></div> </template> ...

Error: JavaScript object array failing to import properly

In my code, I have an array of objects named trace which is defined as follows: export const trace: IStackTrace[] = [ { ordered_globals: ["c"], stdout: "", func_name: "<module>", stack_to_render: [], globals: { c: ["REF" ...

Error alert: TypeScript typings issue - Naming conflict with Promise / Failure to locate name Promise

I am currently working on a client/server JavaScript application and I am facing a significant issue with Promises. It appears that they are either undefined or duplicated, and this problem seems to be related to the @types package. npm install --save @ty ...

An error in typescript involving a "const" assertion and a string array

Currently, I am diving into the world of Typescript along with React. However, an error has emerged in my path that I can't seem to figure out. It's puzzling why this issue is occurring in the first place. Allow me to elaborate below. const color ...

Try uploading a file with the imageUpload function in JavaScript, could be something basic

Today I successfully uploaded a picture using a basic button (id: "imageUpload") to select and upload a file. Everything worked flawlessly, with the thumbnail of the picture appearing in "thumb1." Now, I am attempting to allow users to upload a picture by ...

Error in AngularJs: [$injector:modulerr] Unable to create schemaForm module instance

Trying to integrate angular-schema-form into AngularJs Seed has been a challenge. Following the steps outlined in the angular-schema-form repository: view1.js 'use strict'; angular.module('myApp.view1', ['ngRoute', 'sc ...

Issue with importing React: 'Module not found: Unable to locate'

I've organized my React project with a folder system, as shown in the screenshot below: https://i.stack.imgur.com/Rl9Td.png Currently, I'm attempting to import from context.js, located in src/context.js, into index.js, found in src/components/K ...

Tips for utilizing jquery.load for fetching a section of an html document or an entire html file

I'm experimenting with jquery's load function to dynamically fetch and display HTML content, rather than using $.ajax(). I enjoy exploring the various features that jQuery offers and want to understand how each one works. Below is the code I am ...