Generating a collection of nested objects from an array of non-nested objects

If I were to present an array like the one below:

[  
   {  
      'id':48,
      'parent':0,
      'order':1
   },
   {  
      'id':49,
      'parent':48,
      'order':2
   },
   {  
      'id':50,
      'parent':0,
      'order':3
   },
   {  
      'id':51,
      'parent':48,
      'order':4
   },
   {  
      'id':52,
      'parent':0,
      'order':5
   },
   {  
      'id':53,
      'parent':50,
      'order':6
   },
   {  
      'id':54,
      'parent':50,
      'order':7
   }
]

I am seeking a solution that involves writing Javascript code in either an Angular controller or utilizing ng-repeat within the view to generate the following output:

  [  
   {  
      'id':48,
      'parent':0,
      'order':1,
      'children':[  
         {  
            'id':49,
            'parent':48,
            'order':2
         },
         {  
            'id':51,
            'parent':48,
            'order':4
         }
      ]
   },
   {  
      'id':50,
      'parent':0,
      'order':3,
      'children':[  
         {  
            'id':53,
            'parent':50,
            'order':6
         },
         {  
            'id':54,
            'parent':50,
            'order':7
         }
      ]
   },
   {  
      'id':52,
      'parent':0,
      'order':5
   },

]

The initial array is expected to be sorted by order already, and it's necessary for the output to uphold this ordering.

The current approach I have taken does function as intended. It consists of using ng-repeat along with a conditional statement to verify if the given object has a parent.

In essence, my strategy involves using ng-repeat to display all parents first, followed by iterating through the entire array repeatedly for each parent to identify children. However, this method incurs significant performance costs and becomes sluggish when dealing with arrays containing over 40-50 objects. Additionally, as the depth increases, so do the performance issues. Although I aim to accommodate up to five levels of nesting, my existing looping mechanism falls short.

My goal is to optimize this process within the controller to minimize the workload for ng-repeat.

Did anyone take the time to review my current solution? Since there are implications of receiving assistance effortlessly *eyeroll*

<div class="comments">
        <span></span>
        <ul>
            <li class="comment byuser comment-author-solopine bypostauthor even thread-even depth-1" id="comment-21">
                <span></span>
                <div class="thecomment">
                    <span></span>
                    <div class="author-img">
                        <span><img alt="" class="avatar avatar-60 photo" height="60" src="{{%20comment.author_avatar_urls['96']%20}}" width="60"></span>
                    </div><span></span>
                    <div class="comment-text">
                        <span><span class="reply"><a class="comment-reply-link scroll" href="" rel="nofollow">Reply</a></span></span>
                        <h6 class="author">{{ comment.author_name }}</h6><span class="date">{{ comment.date | date : 'longDate' }}</span>
                        <p></p>
                        <div></div>
                        <p></p>
                    </div>
                </div>
            </li>
            <li style="list-style: none">
                <span></span>
                <ul class="children">
                    <li class="comment byuser comment-author-solopine bypostauthor odd alt depth-2" id="comment-24">
                        <span></span>
                        <div class="thecomment">
                            <span></span>
                            <div class="author-img">
                                <span><img alt="" class="avatar avatar-60 photo" height="60" src="{{%20childComment.author_avatar_urls['96']%20}}" width="60"></span>
                            </div><span></span>
                            <div class="comment-text">
                                <span><span class="reply"><a class="comment-reply-link" href="" rel="nofollow">Reply</a></span></span>
                                <h6 class="author">{{ childComment.author_name }}</h6><span class="date">{{ childComment.date | date : 'longDate' }}</span>
                                <p></p>
                                <div></div>
                                <p></p>
                            </div>
                        </div>
                    </li><!-- #comment-## -->
                </ul><!-- .children -->
                <!-- #comment-## -->
            </li>
        </ul>
    </div>

As previously mentioned, leveraging ng-repeat.

Answer №1

One way to manage parent-child relationships is by using an object for lookup and insertion purposes.

It's important to note that this approach assumes the parent nodes are inserted before their respective children.

var data = [{ 'id': 48, 'parent': 0, 'order': 1 }, { 'id': 49, 'parent': 48, 'order': 2 }, { 'id': 50, 'parent': 0, 'order': 3 }, { 'id': 51, 'parent': 48, 'order': 4 }, { 'id': 52, 'parent': 0, 'order': 5 }, { 'id': 53, 'parent': 50, 'order': 6 }, { 'id': 54, 'parent': 50, 'order': 7 }],
    tree = [];

data.forEach(function (a) {
    this[a.id] = { id: a.id, parent: a.parent, order: a.order };
    this[a.parent].children = this[a.parent].children || [];
    this[a.parent].children.push(this[a.id]);
}, { 0: { children: tree } });

console.log(tree);

This code snippet provides a solution for unsorted data while preserving the desired sort order.

var data = [{ 'id': 54, 'parent': 50, 'order': 7 }, { 'id': 53, 'parent': 50, 'order': 6 }, { 'id': 49, 'parent': 48, 'order': 2 }, { 'id': 51, 'parent': 48, 'order': 4 }, { 'id': 52, 'parent': 0, 'order': 5 }, { 'id': 48, 'parent': 0, 'order': 1 }, { 'id': 50, 'parent': 0, 'order': 3 }, ],
    tree = function (data) {
        var r = [], o = { 0: { children: r } };
        data.forEach(function (a) {
            var p = 0,
                temp = { id: a.id, parent: a.parent, order: a.order };
            if (o[a.id] && o[a.id].children) {
                temp.children = o[a.id].children;
            }
            o[a.id] = temp;
            o[a.parent] = o[a.parent] || {};
            o[a.parent].children = o[a.parent].children || [];                    
            o[a.parent].children.some(function (a) {                        
                if (a.order > temp.order) {
                    return true;
                }
                p++;
            });
            o[a.parent].children.splice(p, 0, temp);
        });
        return r;
    }(data);

console.log(tree);

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

What is the best method for arranging checkboxes in a vertical line alongside a list of items for uniform alignment?

Trying to come up with a solution to include checkboxes for each item in the list, maintaining even vertical alignment. The goal is to have the checkboxes in a straight vertical line rather than a zigzag pattern. Coffee Nestle ...

Deactivate DropDownList within Update Panel with JQuery

Below is the Update Panel that I am working on: <asp:ScriptManager ID="ScriptManager1" runat="server" /> <asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server"> <Triggers> <asp:AsyncPostBackTrigger ControlID="d ...

C# Array of Buttons

Here is the code snippet I am trying to use: Button[] ButtonArray = { btn1, btn2, btn3 }; for (int i = 0; i >= 3; i++) { ButtonArray[i].Text = loadData[i]; } My goal is to load data from the loadData array into the text property of buttons btn1, ...

Error message indicating unfulfilled peer dependency in Ionic Angular when using npm

Having trouble integrating the angular google maps package npm install @agm/core Encountering errors with unmet peer dependencies, unsure of the reason. Could it be that the version of Angular in my project is incompatible with the agm/core package? This ...

Using TypeScript, what is the best way to call a public method within a wrapped Component?

Currently, I'm engaged in a React project that utilizes TypeScript. Within the project, there is an integration of the react-select component into another customized component. The custom wrapped component code is as follows: import * as React from " ...

Struggling to jest mock the useLocation hook in a React component that has been shallow mounted

Currently, I am working on testing a component that relies on the useLocation react hook. Despite my efforts to mock it, I keep encountering an error when trying to access useLocation().pathname because useLocation is undefined. Additionally, I have a que ...

How come my Calendar is not showing up on the browser?

I came across a helpful guide on setting up a Calendar in HTML using JavaScript You can find it here: Unfortunately, the code I tried to use based on that guide isn't functioning as expected. <div class="row"> <div class="col-lg-4 text ...

What is the solution for resolving the "Module Not Found" error when using Node.js and React?

While working on a website with react.js and tailwindcss, everything was working fine on localhost yesterday. However, without making any changes, I am now encountering an error message stating, "Cannot find module." P.S.: Is there an alternative method t ...

Angular and UI Router - the template seems to be loading, however, there is no content displayed on the document

I am currently utilizing Angular 1 in conjunction with UI Router(https://github.com/angular-ui/ui-router). This is how my primary app.js file appears: var myApp= angular.module('myApp', [ 'ui.router' ]); myApp.config(function($s ...

I'm in the process of designing a Todo list platform, but I've hit a roadblock trying to figure out the best way to showcase and delete tasks

Having some trouble with creating an li element even after following the necessary steps. Any guidance and explanation would be greatly appreciated. Thank you Managing HTML and CSS is fine, but when it comes to JavaScript, I always seem to struggle. I und ...

Issues encountered with jQuery's $.ajax function when communicating with PHP

I am having trouble creating a simple app that displays data from a MySQL database using PHP and jQuery. The issue I am facing is with retrieving the data using jQuery. While my PHP script successfully returns the data without any problems, I am not receiv ...

having trouble launching ionic serve following the upgrade to Ionic 2

Recently, I've been revisiting an old Ionic v1 project after working with Ionic v2. However, when trying to run 'ionic serve' in the v1 project's root directory, I encountered the following message: Looks like a fresh checkout! No ./no ...

Display or conceal all sections based on selected dropdown options within the Elementor plugin

I have a dropdown menu with 9 different sections underneath 1. Section id=Hige x 3 2. Section id=Medium x 3 3. Section id=Low x 3 My goal is to show only the sections that correspond to the selection made in the dropdown menu. I am using jQuery to achi ...

Encountering the WRONG_DOCUMENT_ERR: DOM Exception 4 error when attempting to close Fancybox after making edits in inline Tiny

I am encountering a problem with my fancybox that includes a form for collecting user input, which features a tinyMCE editor. When trying to close the fancybox after making substantial edits in the TinyMCE, whether by clicking the close X or submitting the ...

AngularJS: Working with a directive within the UI-Bootstrap modal

I am facing a challenge in trying to invoke a directive from within a modal that is generated using the $dialog service. This directive should also have access to the buttons inside the modal and be able to override their ng-click functionality. Below is ...

Traverse a computed attribute in Vue.js

I am working with a component that contains a simple array as its data: data() { return { roles: [ { id: '1' , name: 'admin'}, { id: '2' , name: 'user'}, { id: &a ...

Develop unique web components and distribute them across various frameworks

Currently, I am working on two projects that utilize Angular and React. I have noticed that certain components are duplicated in both projects. To streamline this process, I am considering creating a company library where I can develop custom components on ...

What is the term for the operation of "pairing each with each"?

I am working with a matrix represented in PHP as an array: array( array('x', 'y'), // x | y array('z', 'w') // z | w ) Now, I have a second matrix also represented in a similar way (without inner a ...

Adjusting the dimensions of an HTML image element in Angular dynamically

Recently, I've been exploring the idea of incorporating a jQuery BeforeAndAfter plugin into my angularJS app. However, I've encountered an issue with dynamically setting the width and height of images with different dimensions. Here's what I ...

Enhance records within an array with multiple nested levels of documentation

I have a JSON structure stored in my MongoDb database and I need to update a specific value within a nested array. Specifically, I want to change the key targetAreaId from USER_MESSAGE to VISUAL_MESSAGE. { "_id" : "5cde9f482f2d5b924f492da2", "scenario" : ...