Creating a tree-like structure from a list of JSON objects using JavaScript

I have a JSON object list that needs to be transformed into a specific structure.

var files = [{name: "1.xml", path: "folder1/1.xml", tag: "folder1", type: "file"},
{name: "2.jpg", path: "folder1/folder2/2.jpg", type: "file", tag: "folder1/folder2"},
{name: "3.doc", path: "folder1/folder2/3.doc", type: "file", tag: "folder1/folder2"}];    

I am looking to create the following hierarchical structure:

[
{
name: "folder1",
path: "folder1",
type: "folder",
items:[
    {name: "folder2", 
     path: "folder1/folder2", 
     type: "folder", 
     items:[
         {name: "2.xml", path: "folder1/folder2/2.xml", type: "file"},
         {name: "3.xml", path: "folder1/folder2/3.xml", type: "file"} 
      ]},
     {name: "1.xml", path: "folder1/1.xml", type: "file"}
]}]

The goal is to convert the 'tag' property of each file into a folder, grouping related files and other tags into an 'items' collection.

Answer №1

One way to address this is by utilizing a recursive function:

function createTree(files) {
    var result = { path: '', items: [] },
        i = 0;
    
    if (!files.length) return [];
    // Ensure files are sorted based on folder hierarchy
    files.sort( (a, b) => a.path.localeCompare(b.path) );
    
    (function recursivelyBuild(curr) {
        var tag = files[i].tag;
        tag.substr(curr.path.length+!!curr.path).split('/').forEach( folder => {
            var obj = {
                name: folder,
                path: (curr.path ? curr.path + '/' : '') + folder,
                type: 'folder',
                items: []
            };
            curr.items.push(obj);
            curr = obj;
        });
        while (i < files.length) {
            var file = files[i];
            if (file.tag.indexOf(tag + '/') === 0) {
                recursivelyBuild(curr);
            } else if (file.tag === tag) {            
                curr.items.push({
                    name: file.name,
                    path: file.path,
                    type: 'file'
                });
                i++;
            } else {
                break;
            }
        }
    })(result);
    return result.items;
}

// Sample data
var files = [
{name:"1.xml", path:"folder1/1.xml",         type:"file", tag:"folder1"},
{name:"2.jpg", path:"folder1/folder2/2.jpg", type:"file", tag:"folder1/folder2"},
{name:"3.doc", path:"folder1/folder2/3.doc", type:"file", tag:"folder1/folder2"},
{name:"4.doc", path:"folder1/folder23/3.doc", type:"file", tag:"folder1/folder23"},
{name:"5.doc", path:"folder12/3.doc", type:"file", tag:"folder12"},
];

// Transform into tree structure
var tree = createTree(files);
// Display output
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

Tips on gathering information from an HTML for:

After encountering countless programming obstacles, I believe that the solution to my current issue is likely a simple fix related to syntax. However, despite numerous attempts, I have been unable to resolve it thus far. I recently created a contact form ...

Having trouble with the Ajax load function not functioning in your HTML code?

The issue has been resolved. Thank you to everyone who helped! Initially, I was attempting to run a file offline instead of on a web server (XAMPP server). Once I uploaded the file to the web server, it started working properly. I had been trying to load ...

Loading TreeStore with dynamic parameters on ExtJs: A comprehensive guide

My tree with treestore initially loads successfully, but encounters issues when attempting to fetch children nodes. During the child node request, a parameter called localpath is sent to specify the location where the children data can be found. For the ...

Setting a Minimum Height in Bootstrap for a Div

I am currently working on designing a page with a banner using bootstrap. The image, which has the id "mybanner," is generated dynamically from the code. This means that there are occasions where the image element may not exist within my code. To ensure co ...

What is the method for selecting a specific row in a Primefaces Datatable using HtmlUnitDriver and Selenium?

Check out this code snippet: import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriv ...

Challenge with the Nested List Weight Sum algorithm

Trying to crack the challenge "Nested List Weight Sum": Challenge: If given the list [[1,1],2,[1,1]], the expected output is 10. (four 1's at depth 2, one 2 at depth 1) Here's my approach. function calculateDepthSum(nestedList, sum=0, dept ...

Every time I switch to a new Vue.js route, I find myself inexplicably redirected to the bottom of the page, leaving me scratching my head in confusion

I'm really struggling to understand why this issue is happening because there doesn't seem to be any code that would interfere with the scrolling. Every time I click on the link, it immediately takes me to the bottom of the view. I'm not sur ...

Passing arguments from the server to the client

Here is some code that I am working on which includes a dropdown and a JavaScript function being called from the server side. I am having trouble passing a parameter to the JavaScript function. Can anyone help me resolve this issue? Server-side code: Pa ...

Converting Dynamic Objects into Class Instances

I've been grappling with this issue for the past day or so and I just can't seem to pinpoint why it's occurring. Right now, my goal is to deserialize a dynamic object into a class for usage. However, no matter what I do, I keep encountering ...

Steps for redirecting to an external URL with response data following an HTTP POST request:

this.http.post<any>('https://api.mysite.com/sources', [..body], [...header]) .subscribe(async res => { const someData = res.data; const url = res.url; window.location.href = url }) After redirecting to the specified UR ...

The act of transferring non-textual information into web-based applications

Is it possible for a user to copy and paste a selection of pixels from MSPaint into a browser-based app using JavaScript in current browsers? If not, will HTML5 make this possible in the future? Alternatively, could something like Flex or Silverlight be us ...

Effortlessly incorporating a new textbox into your design

My page currently has 8 textboxes, but I find it to be too cluttered. I am considering adding a button that users can click to dynamically add more textboxes. Does anyone have any ideas or solutions for how I can implement this? Any assistance would be g ...

What is the best way to insert an anchor tag into text using React?

I am working with a variable const linkElement = `Hey this is a link ${<a href="www.google.com">Click me!</a>} that can be clicked}` Currently, it displays as Hey this is a link [Object object] that can be clicked. Is there a way to ...

Triggering server-side code (node.js) by clicking a button in an HTML page created with Jade

I am currently working on developing a web application and have encountered an issue where I need to execute some server-side code when a button is clicked (using the onClick event handler rather than the Submit button). My tech stack includes Node.js, Exp ...

Download the ultimate HTML package with a built-in chart.js component directly from your nuxt app

I have a task to create a compact Nuxt application that produces a basic HTML file containing informative sections about the services offered to the clients of my organization. The main purpose is to generate an HTML file that can be easily downloaded and ...

Error: Missing semicolon at line 1005 in Vue computed function. Vetur is indicating this issue

As a beginner in vue3, I am venturing into building some side projects. However, I keep encountering an error message stating ';' expected.Vetur(1005) when attempting to utilize the computed function. Strangely enough, sometimes the same syntax w ...

Refreshing the page results in a 404 error when utilizing React Router

I am currently facing an issue with my web application setup. Back-End My back-end consists of a Node.js/express server that serves files in response to specific requests made to certain routes. Front-End On the front-end, I have React pages that commu ...

Creating a React component dynamically and applying unique custom properties

I'm currently in the process of refactoring my React code to enhance its usability in situations where direct use of Babel is not possible, such as in short snippets of JavaScript embedded on web pages. As part of this refactor, I am setting up a conc ...

Stack required: \ Error, this is a new one to me

throw err; ^ Error: The module './C:\Users\domri\OneDrive\Desktop\Repositories\Discord Bot\commands\test/ping.js' cannot be located The error seems to be originating from this section of the code const ...

The computer system encountered an issue in computing the values of the text

Possible Duplicate: Unable to get textfield value using jQuery My current project involves updating input fields based on user changes in quantity for items. Each item is retrieved from a database and I am generating invoices for customers. However, ...