Changing an array of objects into nested objects in JavaScript

Currently, I have been assigned the task of organizing the files directory efficiently. All documents and files are stored in a flat array for simplicity. Each file has a uniqueId property that indicates its parent directory. The flat array is sorted based on the uniqueId, ensuring that each child follows its parent.

Here is an illustration of the flat array:

[{
 id: 1,
 uniqueId: '1',
 name: 'folder1',
 dir: true
},
{
 id: 2,
 uniqueId: '1.2',
 name: 'test1',
 dir: false
},
{
 id: 3,
 uniqueId: '1.2.3',
 name: 'test2'
 dir: false
},
{
 id: 4,
 uniqueId: '1.2.4',
 name: 'test3'
 dir: true
},
{
 id: 3,
 uniqueId: '1.3',
 name: 'test23'
 dir: true
},
{
 id: 1,
 uniqueId: '1.3.1',
 name: 'test6',
 dir: true
},
]

This effectively represents the file directory tree:

1
  1.2
    1.2.3
    1.2.4
  1.3
    1.3.1

The objective is to display directories first, specifically those with dir: true. Consequently, the tree above would be reordered as follows:

1
 1.3
    1.3.1
 1.2
    1.2.4
    1.2.3

To achieve this, I have decided to convert the flat array into nested objects, arrange the children of each object accordingly, and then revert back to a flat array structure. This means transforming the flat array into the following format:

{
 id: 1,
 uniqueId: '1',
 name: 'folder1',
 dir: true
 childs: [
  {
   id: 2,
   uniqueId: '1.2',
   name: 'test1',
   dir: false,
   childs: [
   {
     id: 3,
     uniqueId: '1.2.3',
     name: 'test2'
     dir: false
   },
   {
     id: 4,
     uniqueId: '1.2.4',
     name: 'test3'
     dir: true
   }
 ]},
 {
   id: 3,
   uniqueId: '1.3',
   name: 'test23'
   dir: true,
   childs: [
    {
     id: 1,
     uniqueId: '1.3.1',
     name: 'test23'
     dir: true
    }
  ]
}
}]

I am struggling to find a way to convert the flat array into the desired nested object configuration. While I do have a function that returns a current object's children isChild(parent, objectToCheck), incorporating recursion seems necessary but challenging.

If you can provide assistance in converting it into the desired nested object, I would greatly appreciate it.

Furthermore, any alternative suggestions for sorting the flat array are welcomed! Perhaps there exists a more efficient technique without the need to constantly switch between structures?

Thank you sincerely in advance!

Answer №1

If you want to organize the data efficiently, consider sorting it directly and creating a hierarchical tree structure using uniqueId along with a parent value.

const
    inputData = [{ id: 1, uniqueId: '1', name: 'folder1', dir: true }, { id: 2, uniqueId: '1.2', name: 'test1', dir: false }, { id: 3, uniqueId: '1.2.3', name: 'test2', dir: false }, { id: 4, uniqueId: '1.2.4', name: 'test3', dir: true }, { id: 3, uniqueId: '1.3', name: 'test23', dir: true }, { id: 1, uniqueId: '1.3.1', name: 'test6', dir: true }],
    structuredTree = function (data) {
        var treeStructure = {};
        data.forEach(obj => {
            const parentNode = obj.uniqueId.split('.').slice(0, -1).join('.');
            Object.assign(treeStructure[obj.uniqueId] = treeStructure[obj.uniqueId] || {}, obj);
            treeStructure[parentNode] = treeStructure[parentNode] || {};
            treeStructure[parentNode].children = treeStructure[parentNode].children || [];
            treeStructure[parentNode].children.push(treeStructure[obj.uniqueId]);
        });
        return treeStructure[''].children;
    }(inputData.sort((a, b) => b.dir - a.dir));
   
console.log(structuredTree);
.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

Copying the output of the built-in qsort() function in C into a separate array

My goal is to utilize the built-in qsort() function in C for sorting an array. Here is the code snippet I have written: #include <stdio.h> #include <string.h> #include <stdlib.h> int cmpfunc (const void * a, const void * b) { return ...

Creating a Jasmine test for the event.target.click can be accomplished by defining a spec that

I need help creating a Jasmine test spec for the following method in my component. Here is my Component Method methodName(event): void { event.preventDefault(); event.target.click(); } I have started writing a test but don't fully cover event. ...

The event is being triggered on two separate occasions

Hey there! I'm trying to bind the onclick event to both a parent and child element using the same method. However, I'm running into an issue where the event is being fired twice. Any suggestions on how to prevent this from happening? <div id= ...

Enhancing Real-time Communication with NodeJS and NowJs Servers

Recently, I stumbled upon NodeJS and NowJS and I'm fascinated by the technology. My goal is to develop a Facebook-style instant commenting application where users can post comments that will instantly appear on the feed. After watching the screencast ...

Using filter in JavaScript to manipulate an array of array objects: what you need to know!

Currently, I am working with an array that contains the following values: var array1 = ['new_user', 'promotion'] My task is to filter out an object from OBJc based on this array1: OBJc = [ {"id": 1, "array_": [& ...

The array_search function is not functioning as anticipated when used with a multi-dimensional array

Looking for the key of a value in a multidimensional array? Check out the example below: $array = array( 'USD' => array ( 0 => 1.79, 1 => 3.58, 2 => 5.37, 3 => 7.16, 4 => 8.95, ), 'CAD ...

Finding it difficult to differentiate shapes based on the number of sides

Seeking to identify the type of shape based on the number of sides passed in. The code provided only recognizes the first index, which is a triangle. I suspect this is because I am not correctly comparing the number of sides to the sides property in the ...

This jQuery ajax request is returning a readyState of 1 or an incorrect data type

I am currently troubleshooting an issue with the ajax response in my Wordpress plugin script. Whenever I try to retrieve a json file using jQuery.ajax, I receive {readyState: 1} as the result. Even when setting async: false, the response is always plain te ...

When I try to send data from my Node.js application to my MySQL database, the information does not

I am currently working on developing a registration and login page, where the user details are stored in a database for authentication during login. The registration button is meant to store user data in the database to complete the sign-up process. For t ...

Can React Slick be configured to display a Carousel within another Carousel?

Can React Slick support a Carousel within another Carousel? import Slider from "react-slick"; <Slider {...settings} > <div/> <div> <Slider {...settings} > ...

Submit a document through a jQuery post method in conjunction with PHP

Is there a way to upload a file without using a form and instead utilizing $.post method to transfer the file? I suspect that the issue lies within the PHP code, although I can't be certain. <input type='file' id='inpfile'> ...

Adding a randomly generated number into a sorted C++ array

At the moment, I am attempting to create an array that can insert a random number while still keeping the array in proper order. For instance, if the array currently consists of 10, 20, and 30, and the random number is 11, the function should insert it aft ...

Integrating a fresh element into the carousel structure will automatically generate a new row within Angular

I'm currently working on an Angular4 application that features a carousel displaying products, their names, and prices. At the moment, there are 6 products organized into two rows of 3 each. The carousel includes buttons to navigate left or right to d ...

Obtain the total count for each 2-dimensional array

I have an array of strings generated using numpy: np.random.seed(343) arr = np.sort(np.random.randint(5, size=(10, 10)), axis=1).astype(str) print (arr) [['0' '1' '1' '2' '2' '3' '3' & ...

Top method for creating a checkbox filter to toggle the display of elements depending on various data-* attributes

I am currently working on creating a checkbox filter that will display or hide elements based on multiple data attributes assigned to those elements. Despite my attempts, I have not been able to achieve the desired filtering outcome. You can view a basic ...

Dealing with multiple POST requests at once in Node Express JS - Best Practices

I've been working on a Node project with Express to handle incoming GET/POST requests. I have set up routes to manage various types of requests. One specific route, /api/twitter/search, calls a function that uses promises to retrieve Twitter feeds and ...

The lifespan of an Angular controller and its management of events

What is the best way to manage events, such as $rootScope or socket events, in an Angular controller without causing issues with event duplication? I have noticed that my controllers are not being destroyed properly, leading to problems when it comes to li ...

Learn how to assign an image to a div element when it is collapsed, and then reveal the content when clicked on to expand

I am working on a three div with expand collapse functionality. When I expand one div, I want to set some image to the other divs. And when I go back to normal mode, I need the original content that was inside each div. $("a.expansion-btn").click(functi ...

`MarkdownParser encounters bug in handling internal arrays during Newtonsoft DeserializeXNode process`

There is a JSON object with properties like: { "property1": "value1", "property2": "value2", "property3": ["value3","value4","value5"] } However, when attempting to convert it to XML using DeserializeXNode, the array is not preserved. <MyObj> ...

JavaScript Function Failing to Produce Output

I have created a function that reduces two numbers using the relationship of fractions. The function is working perfectly, but there is an issue with it not returning the value as expected. I have tried different approaches such as declaring a new variable ...