Traversing a nested array in JavaScript to create a nested object in a loop

Struggling with translating a depth list into a nested object.

Consider this list:

"depth": [ 0, 1, 2, 3, 3, 2, 3, 3, 3 ],

I'm trying to create a recursive function that generates an object like this:

"depth": [
        {
            "type": 0,
            "children": [
                {
                    "type": 1,
                    "children": [
                        {
                            "type": 2,
                            "children":[
                                { "type": 3, "children": []},
                                { "type": 3, "children": []},
                            ]
                        },
                        {
                            "type:": 2,
                            "children":[
                                { "type": 3, "children": []},
                                { "type": 3, "children": []},
                                { "type": 3, "children": []},
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}

The lower numbers represent parents, while the higher numbers are siblings of the previous lower number.

I've managed to map children to parents in my code so far, but I'm struggling with generating the final result. Any suggestions would be greatly appreciated.

Thanks!

Answer №1

One efficient way to construct a tree structure is by utilizing a Map or dictionary (object) for easy parent retrieval. By transforming the entire tree into a Map, it becomes simpler to access the root node which represents the complete tree.

const createNode = (type) => ({ type, children: [] })

const buildTree = (arr, root) => arr.reduce((acc, d) => {  
  const parent = d - 1
  
  const node = createNode(d)
  
  if(d !== root && !acc.has(parent)) acc.set(parent, createNode(parent))
  
  if(d !== root) acc.get(parent).children.push(node)
  
  return acc.set(d, node);
}, new Map()).get(root);

const depthLevels = [0, 1, 2, 3, 3, 2, 3, 3, 3 ]

const finalTree = buildTree(depthLevels, 0)

console.log(finalTree)

Answer №2

When receiving the data in pre-order sequence, it is unnecessary to use a map:

function convert(data) {
    let i = 0;
    
    function getChildren(type) {
        let children = [];
        while (data[i] === type) {
            i++;
            children.push({
                type,
                children: getChildren(type + 1)
            });
        }
        return children;
    }
    
    return getChildren(0);
}

let data = [0, 1, 2, 3, 3, 2, 3, 3, 3];
console.log(convert(data));

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

Adjusting the height of an element in AngularJS based on its width dynamically

I am working on a table that is generated using ng-repeat, and I want to ensure that each td in the tbody is square. Since all the tds have an equal width, I only need to adjust the first one. However, the size of the table and td will change when the wind ...

Transmitting HTML5 application settings via URL

I am interested in creating an HTML5 app that utilizes the WebAudio API. This app will allow users to customize certain parameters. Users should be able to 'share' these settings by sending a share URL, which can be clicked by others to view the ...

What is the correct way to customize colors for specific components in Material-ui?

Struggling with theming in Material-UI, particularly when it comes to customizing element colors. Some elements default to 'theme.palette.main.dark' and I want to override this behavior. For example, the TextField and SpeedDial components automa ...

Having trouble with Fancybox loading images from an external URL?

Here is an example of functioning HTML code: <a class="fancybox-gallery" href="http://sale.coupsoft.com/uploads/938218/logo.png"> <img class="animate scale animated" src="http://sale.coupsoft.com/uploads/938218/logo.png" alt="Image1"> ...

Guidelines for utilizing a loader to handle a TypeScript-based npm module

I am currently facing a challenge with my React and JavaScript project as I attempt to integrate an npm module developed with TypeScript. The issue lies in configuring my project to compile the TypeScript code from this module, resulting in the error messa ...

Autocomplete feature in Material-UI does not trigger the onChange event when a chip

I've encountered a quirk with the Material UI Autocomplete component. It seems that when I delete a tag directly from the chip using the (x) button, the onchange function of the autocomplete isn't triggered. Does anyone know how I can ensure that ...

Issue with Abide Validation Events not triggering in Reveal Modal for Foundation Form

Currently, I am developing a login/registration feature for a basic web application using Foundation. On the index page, users are presented with a login screen and a register button. When the user clicks on the register button, a Reveal Modal pops up cont ...

Can Express.Multer.File be inserted into a FormData object easily?

Can anyone assist me in figuring out how to add a file of type Express.Multer.File into a FormData object? Situation: I have received a file with the type Express.Multer.File (I am using nestjs and followed this part of the documentation: https://docs.nes ...

Sluggish Bootstrap Carousel Requires Mouseover or Click to Start Sliding

Having Trouble with Bootstrap Carousel Sliding: I've been trying to solve this issue for a while now, but nothing seems to be working. I know this might be a common question, but I really need to fix this problem quickly and none of the suggested solu ...

Utilizing the power of AWS Lambda in conjunction with moment JS to generate unique

My current time zone is GMT+8, and the AWS region I am using is Singapore (ap-southeast-1). I am facing an issue where there are discrepancies in date calculations between my local machine and when I deploy my code on AWS Lambda. My goal is to ensure that ...

What is the reason that Gatsby's arrow function is unable to access a value from props that is calculated from a promise?

Could someone shed light on why the key value is showing as undefined within the arrow function: // in parent component const Parent = () => { const [key, setKey] = useState<string>(); // this contains an expensive function we on ...

Can the value of a key be changed to match the condition in a find() query when using Mongoose?

Having been well-versed in Oracle, I was thrown into a project requiring the use of a MongoDB database. Utilizing mongoose to connect to my MongoDB, my main query is whether it is possible to match a find condition before executing a query. For example, if ...

Incorporating traditional Bootstrap styling directly into a React application without relying on the react-bootstrap library

My goal is to incorporate my existing bootstrap components into a React project without having to rewrite them to work with the react-bootstrap library. While I have successfully integrated the bootstrap CSS, I am facing issues with the functionality aspec ...

Tips for adjusting the size of a three-dimensional cylinder in three.js

I am working on a project with a basic hollow cyclinder created using three.js, much like the one in the JSFiddle provided. I am curious to know how I can adjust the thickness of the walls of the cylinder in my scene. var scene = new THREE.Scene(); var ca ...

Tips for storing and retrieving high scores in a JavaScript game

I've just finished creating a JavaScript snake game and now I'd like to add a "scores" option that displays the top 10 players along with their names and scores. My initial plan was to create an object containing the player's name and score ...

How can you effectively manage Click events within a three.js environment?

I'm working with a world map layer as a plane geometry and I need to handle click events on different parts, such as continents or countries. I want to show popup events on specific parts like information, videos, or image data with links. How can I a ...

AngularJS - Array binding issue not updating in directive

I am currently developing a directive that has the ability to display a series of controls. Each individual control is implemented as a directive named fsFilter. In the controller managing the parent element, I establish a binding between the filters arra ...

Validation of check boxes in AngularJS group

Struggling to enforce the selection of at least one checkbox from a list using AngularJS validation. Here's the code I've been working with: // JavaScript code snippet var app = angular.module('App', []); function Ctrl($scope) { $ ...

verifying that all characters in an array are permissible

Can someone explain why this code always returns false even when I enter "abcdef" into the prompt, which should make it return true? var userinput = prompt('Enter characters:'); var lowercase = userinput.toLowerCase(); var allowedcharacters = ...

CSS footer element refuses to disappear

This sample application features a header, footer, and a content div that includes a table displaying various statistics of basketball players. One issue I encountered was with the footer when there were many entries in the table. This caused the footer t ...