Transforming a collection of string arrays into a tree format, as well as reversing the process to convert the tree back into a list of string arrays

I am working with a sorted array containing lists of string arrays:

0:['BS', 'MS','KHB', 'CCBPO']
1:['BS', 'MS','KHB', 'HBPO']
2:['BS', 'MS','KHB', 'PBPO']
3:['BS', 'PO','BC', 'BC']
4:['H', 'I','SS', 'ESS']
5:['H', 'I','SS', 'E']
6:['H', 'D','PCD', 'D']
7:['H', 'D','P', 'HP']
ECT

It can be noted that the first parent is always in the first position, like for example 'BS' and 'H', followed by the rest.

Converting this information into a hierarchical structure, the first row would look like this:

{
          "name": "BS",
          "children": [
            {
              "name": "MS",
        "children": [
            {
              "name": "KB",
        "children": [
            {
              "name": "KHB",
        "children": [
            {
              "name": "CCBPO",
              "isTrue": false
            },
              "isTrue": false
            },
              "isTrue": false
            },
              "isTrue": false
            },
              "isTrue": false
            },
        "isTrue": false

}

For subsequent rows, we need to check if the parent is the same and add the child in the correct position. For example, in the second row, the child will be added at the end.

Once this hierarchy is established, I intend to convert it into a structured table format. For the initial 4 rows, this conversion would look something like:

0:['BS', 'MS','KHB', 'CCBPO']
1:['', '','', 'HBPO']
2:['', '','', 'PBPO']
3:['', 'PO','BC', 'BC']

This transformation will allow me to visualize the tree data in a tabular manner.

Answer №1

Looks like we have some work cut out for us - a recursive function is needed here. A recursive function calls itself under certain circumstances.

We will be creating a function that returns an array with names and children. The children are elements of the array where the first element matches the property name.

Let's start by creating createTreeAtempOne(array: any[]):


const tree = array.reduce((a: any, b: any) => {
  const el = a.find((x) => x.name == b[0]);
  if (el) 
    el.children.push(b.slice(1));
  else
    a.push({
      name: b[0],
      children: [b.slice(1)],
    });
  return a;
}, []);

If we feed this function with ['AA'], it should return something like:

{
  "name": "AA",
  "children": [
    []
  ]
}

But we don't want empty arrays for children. So let's modify the function to create createTreeAtempTwo(array: any[]):


const tree = array.reduce((a: any, b: any) => {
  const el = a.find((x) => x.name == b[0]);
  if (el){
    if (el.children)
      el.children.push(b.length > 1 ? b.slice(1) : b[0]);
    else
      el.children=[b.slice(1)]
  } else
    a.push(
      b.length > 1
        ? {
            name: b[0],
            children: [b.slice(1)],
          }
        : {name:b[0]}
    );
  return a;
}, []);
return tree;

Now, feeding this function with ['AA'] should return:

{
  "name": "AA"
}

Great! Now let's add recursion to our function in order to handle different values like [['AA'],['AA','BB']], etc.


createTree(array: any[]) {
  const tree = array.reduce((a: any, b: any) => {
    const el = a.find((x) => x.name == b[0]);
    if (el) {
      if (el.children)
        el.children.push(b.length > 1 ? b.slice(1) : b[0]);
      else
        el.children=[b.slice(1)];
    } else {
      a.push(
        b.length > 1
          ? {
              name: b[0],
              children: [b.slice(1)],
            }
          : {name:b[0]}
      );
    }
    return a;
  }, []);
  
  tree.forEach((t) => {
    if (t.children) t.children = this.createTree(t.children);
  });
  
  return tree;
}

After testing against different values, the function seems to be working!

You can check out the code on StackBlitz. Alternatively, you could simply use

<pre>{{tree|json}}</pre>
to display the 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

Issue encountered: TypeScript compiler (tsc) failed to compile a dependent library within a project, specifically one that depends on a JavaScript library and @types typing package

Imagine a scenario where a library, let's name it LibraryA, relies on another library called js-yaml without type definitions. To make this work, LibraryA has a devDependency called @types/js-yam in its package.json. LibraryA itself compiles smoothly. ...

Update state within React components without impacting any other state variables

Imagine I have an object structured like this: person : { name : "Test", surname : "Test", age : 40, salary : 5000 currency : "dollar", currency_sign : "$", . . . } I am looking to achieve the following I will make ...

Steps for deploying an Ionic 4 app on the Firebase console

I'm encountering issues deploying my Ionic app on the Firebase console. Here are the steps I've taken: Created a new Ionic project Ran firebase init and firebase deploy commands Unfortunately, I cannot seem to view the Ionic output after depl ...

Can a javascript variable be integrated into JRoute() function?

function getProduct(category) { document.star.action = '<?php echo JRoute::_('index.php?option=com_virtuemart&view=category&virtuemart_category_id='+ category) ?>'; document.getElementById('star').submit( ...

Guide to extracting the JSON array from a JSON object with Angular

In my angular application, I have made a call to the API and retrieved a JSON object in the console. However, within this JSON object, there are both strings and arrays. My task now is to extract and parse the array from the object in the console. The JSO ...

Provide information to spyOn and return a specific value

I am attempting to mimic a call to a service that involves an HTTP call. My goal is to provide fabricated data in the mock and verify it during my test. This is how I have set up the scenario: beforeEach(() => { fixture = TestBed.createComponent(MhS ...

Pipe for Angular that allows for searching full sentences regardless of the order of the words

I am looking to create a search bar that can search for the 'title' from the table below, regardless of the word order in the sentence. I attempted to use a filter pipe to check if the search string exists in the title. I also experimented with ...

Guide on how to verify if a component with a specific name is registered within the Composition API of Vue 3

My current situation involves a template that loads dynamic components based on their names: <template> <div> <div> <div> <component :is="getFormRenderer" &g ...

I struggle to grasp the significance of the scene's positioning

I've been experimenting with some sample code using three.js, where I've created a plane and I want it to rotate around. Here's a snippet of my code: This is the setup for my camera: var camera = new THREE.PerspectiveCamera(70, window.inner ...

leveraging parcel for importing typescript dependencies

I am currently using parcel to process typescript for a web extension. I have installed JQuery and its type definitions via npm. In my typescript file, I have the following at the top: import $ from "jquery"; import "bootstrap"; However, when running run ...

The feature to hide columns in Vue-tables-2 seems to be malfunctioning

The issue I'm facing is with the hiddenColumns option not working as expected. Even when I set it to hiddenColumns:['name'], the name column remains visible. I've updated to the latest version, but the problem persists. UPDATE I am tr ...

Creating multiple unique custom attributes for a specialized HTML element

Creating getter/setter methods for a custom attribute on a custom HTML element is quite simple: customElements.define('custom-el', class extends HTMLElement { static get observedAttributes() { return ['customAttr'] ...

In the Angular Google Maps API, is it possible to update the attributes of <agm-marker> directly within the TypeScript code?

Currently, I am fetching markers from the database and displaying them on a map using Angular Google Maps (AGM) by utilizing the <agm-marker> tag. In my code snippet below, you can see how I fetch and store the markers in an array named markers in t ...

Encountered an issue during the migration process from AngularJS to Angular: This particular constructor is not compatible with Angular's Dependency

For days, I've been struggling to figure out why my browser console is showing this error. Here's the full stack trace: Unhandled Promise rejection: NG0202: This constructor is not compatible with Angular Dependency Injection because its dependen ...

In MUI React, the opacity of the placeholder is customizable and can be easily adjusted. This allows for the placeholder to be hidden

Currently, I am facing an issue with a filled variant TextField from Mui React. I have tried to modify it using theme components, but the placeholder text becomes hidden when the field is not focused. See here for Before Focus And here for On Focus I hav ...

Can you please advise on excluding the entire module in Eslint without encountering any errors?

When I have the following listed in my .eslintignore file: **/*.ts I encounter this issue: Error: All files matched by '.' are ignored. Is there a way to suppress this error? My intention is simply to deactivate eslint for a specific submodule. ...

Using JavaScript to round up the number

I need help rounding numbers in a specific way: Value Expected 0,523% 1% 2,235% 2,5% -0,081% -0,5% -1,081% -1,5% How can I achieve this using JavaScript? Possible Solution: static round (num) { const abs = Math.abs(num); const sign = num ...

Utilizing React JS: Displaying or Concealing Specific Components Based on the URL Path

Is there a way to dynamically change the navbar items based on the URL without having separate navbar components for each side? My current navbar design features 3 links on the left side and 3 links on the right, but I want to display only one side at a ti ...

Validate whether the path parameter in NextJS is null or empty before executing the query

Currently seeking a method to determine if the query value is empty using the path parameter approach. Have a file named pages/search/[variable1].js Below is the code snippet: import { useRouter } from "next/router" const Variable= () => { ...

The error message is: "Cannot access property 'up' of an undefined object within the material UI library using theme.breakpoints."

I am encountering difficulties with the export of makeStyles. Below you can find my code and configuration: import SearchField from "../SearchField"; import { TextField, Select, useMediaQuery, Grid, Button, Box, Fade } from '@material-ui/core&ap ...