Create a hierarchical tree structure using a string separated by dots

I am struggling with organizing a tree structure. :(

My goal is to create a tree structure based on the interface below.

export type Tree = Array<TreeNode>;

export interface TreeNode {
  label: string;
  type: 'folder' | 'file';
  children: Array<TreeNode> | string;
}

For example,

Suppose I have a JSON file like this

{
  "common.header.title": "Header Title",
  "common.footer.btn": "Footer button",
  "common.footer.btn.submit": "Footer Submit",
  "apage.title": "apage Title"
}

The desired output should be as follows.

const out = [
  {
    label: 'apage',
    type: 'folder',
    children: [
      { label: 'title', type: 'file', children: 'apage Title' }
    ]
  }, {
    label: 'common',
    type: 'folder',
    children: [
      {
        label: 'footer', 
        type: 'folder', 
        children: [
          { label: 'btn', type: 'file', children: 'Footer button' },
          {
            label: 'btn', 
            type: 'folder', 
            children: [{ label: 'submit', type: 'file', children: 'Footer Submit' }] 
          },
        ]
      }, {
        label: 'header',
        type: 'folder',
        children: [{ label: 'title', type: 'file', children: 'Header Title' }]
      }
    ]
  }
]

I have come across similar cases on SO, but I struggled to reference and implement them in my scenario.

Answer №1

One can begin by seeking out the desired labels and verifying if the children is represented as an array. If so, this object can then be used to delve into the nested array.

Subsequently, a fresh object should be added.

const
    data = { "common.header.title": "Header Title", "common.footer.btn": "Footer button", "common.footer.btn.submit": "Footer Submit", "apage.title": "apage Title" },
    result = Object
        .entries(data)
        .sort(([a], [b]) => a.localeCompare(b))
        .reduce((r, [path, children]) => {
            const 
                keys = path.split('.'),
                label = keys.pop();
                
            keys
                .reduce((t, label) => {
                    let temp = t.find(o => o.label === label && Array.isArray(o.children));
                    if (!temp) t.push(temp = { label, type: 'folder', children: [] });
                    return temp.children;
                }, r)
                .push({ label, type: 'file', children });

            return r;
        }, []);

console.log(result);
.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

Error: Unrecognized HTML, CSS, or JavaScript code detected in template

I'm currently utilizing the "Custom HTML Tag" option in GTM with my code below, but encountering an error when attempting to publish: Invalid HTML, CSS, or JavaScript found in template. It seems that GTM may not support or recognize certain tag attri ...

How to create a vertically scrollable div within another div by utilizing scrollTop in jQuery

I need assistance with scrolling the #container div inside the .bloc_1_medias div. The height of #container is greater than that of .bloc_1_medias. My goal is to implement a function where clicking on the "next" and "previous" text will scroll the #contai ...

Refresh the Express Server following the file upload

This is a simple express server setup that includes file uploading and reading functionality. const express = require("express") const fileUpload = require("express-fileupload") const cors = require("cors") const morgan = require("morgan") const fs = requi ...

Javascript and CSS combo for creating a stylish fade effect

Hey everyone, I have a design challenge where I need to change the color of a picture inside a box when the user hovers over it. I have four boxes like this and my goal is to make everything else fade out when a user hovers over a specific box. Anyone kn ...

Execute unit tests for the nodejs project

Looking to execute the tests for this project on GitHub? Head over to the test folder on https://github.com/node-opcua/node-opcua. However, I'm unsure about the testing framework that was utilized and how to run all the tests. Any guidance would be mu ...

An error message occurs in TypeScript when trying to access a property that does not exist in an array

I'm having trouble figuring out this issue... I am receiving data from an API and storing it as an array. I'm attempting to access the data in this format... this.data.results[i].datas[j].dataType However, I keep getting the error "property res ...

Is it possible to apply capitalization or convert the value of props to uppercase in React?

Despite attempting the toUpperCase method, I am unable to capitalize my props value. Here's the code I have: export default function Navbar(props) { return ( <> <div> <nav class="navbar navbar-expand-lg bg-b ...

Determine the presence of a Facebook user by using JavaScript

I am trying to find a method to verify the existence of a Facebook user based on their ID. As far as I understand, there is a Graph API that can provide a Facebook user's profile picture using their ID in this format: I have noticed that if an inval ...

"Encountering a problem with using setState in React Hook useEffect

I am currently utilizing the useState hook with two arrays: imageList and videoList. In my useEffect hook, I iterate through the data using forEach method. If the type of the item is an image, it should be pushed to the imageList array. However, after exec ...

Encountered an Error with My Protractor Script - Object Expected

Currently, I am in the process of learning automation testing for an AngularJS application. However, I have encountered an "object expected" error on line 4, which is pointing to the first line of my script. describe("Homepage", function() { it("Navig ...

Troubles with AJAX and jQuery

<html> <head> <title>Ajax Example</title> <script type="text/JavaScript" src="jquery-1.5.1.min.js"></script> <script type="text/JavaScript"> function fetchData() { $.ajax({ type: "GET", url: "htt ...

What is the best way to dynamically load content as it enters the viewport using JavaScript or jQuery?

I have implemented a stunning animation to the h1 element using a function, but now I want the animation to trigger only when the h1 element enters the viewport as the user scrolls down. Currently, the animation occurs as soon as the page is loaded, even ...

My pathways are clearly mapped out, yet express is returning a frustrating 404 error

After exhausting all the similar posts on StackOverflow without finding a solution... Let's take a look at my app.js, which is the first file that the express library seeks when launching the app right after my server.js file responsible for setting ...

When performing an arithmetic operation, the right operand must be a data type of 'any', 'number', 'bigint', or an enumeration type

My JavaScript code needs to be converted to TypeScript for proper functionality. categoryAxis.renderer.labels.template.adapter.add("dy", function(dy, target) { if (target.dataItem && target.dataItem.index % 2 === 0) { return dy + 25; } ...

Code needed to efficiently include a d3 module through webpack

Having some trouble importing and using a d3 module in my webpack project. The function I need from the module is declared like so: https://github.com/d3/d3-plugins/blob/master/hive/hive.js d3.hive.link = function() { I attempted to follow this guide to ...

Using vuetify's v-autocomplete component with the options to select all and clear items

I am trying to incorporate a "Filter by values" feature in my application similar to Excel or spreadsheets. However, I am facing difficulty with implementing the 'Select all' and 'Clear' button in v-autocomplete. <v-col> < ...

Tips on retaining label names for input boxes

Check out this Plunker example. I am trying to figure out how to keep labels on top of textboxes in this Plunker. Can anyone help me with that? <a class="btn btn-success btn-xs" data-nodrag ng-click="toggle(this)"><span class="glyphicon" ng-clas ...

The node.js application was unable to locate the '../HMS/server/models/user' file

Hi there! I'm currently working on an application with a folder structure as shown below. I want to use the following line in my passport.js file: var User = require('../server/models/user'); However, I encountered the error below after tr ...

GAS: What strategies can I implement to optimize the speed of this script?

I have a sheet with multiple rows connected by "";" and I want to expand the strings while preserving the table IDs. ID Column X: Joined Rows 01 a;bcdfh;345;xyw... 02 aqwx;tyuio;345;xyw... 03 wxcv;gth;2364;x89... function expand_j ...

Gulp does not generate any files

Hey there, I'm brand new to using node.js and coding in general. I recently attempted to convert SCSS to CSS using gulp. My gulpfile.js seems to be correct, but when I try running "gulp styles" in the node.js command prompt, I receive the following ou ...