typescript provides an asynchronous recursive mapping function that allows for changing parent data starting from the leaf node

I am currently facing a challenge in identifying the leaf node within a non-binary tree that requires modification. The process involves computing a blake2b hash from the leaf data, passing it to the parent node, and repeating this calculation until reaching the root node where the same computation is performed.

The starting and end interfaces are outlined below:

interface sto {
  name: string
  children: sto[]
}

interface stoWithIds {
  id: string // blake2b(data)
  data: {
    name: string
    children: stoWithIds[]
  }
}

The essential functions needed for this operation are as follows:

function transformSto (op: sto): stoWithIds {
  const { children, ...rest } = op
  return { id: '', data: { ...rest, children: [] } }
}

async function visitNode (node: sto, parent: stowithId) {
  // This will begin execution when a leaf node is identified and progress upwards
  node.children.map(async c => await visitNode(node, parent))

  // Calculating the ids here
  parent.children.push(/* our calculation, but this doesn't work for children on the same level*/)
}

The next step would be to invoke these functions:


const sto: sto = {
  name: 'Root',
  children: [
    {
      name: 'child 1',
      children: [
        {
          name: 'child2',
          children: []
        },
        {
          name: 'child3',
          children: []
        }
      ]
    }
  ]
}
await visitNode(sto, transformSto(sto))

The expected outcome after executing these operations should look like this:

const stowithId: stoWithIds = {
  id: 'blake2b(data)',
  data: {
    name: 'Root',
    children: [
      {
        id: 'blake2b(data)',
        data: {
          name: 'child 1',
          children: [
            {
              id: 'blake2b(data)',
              data: {
                name: 'child2',
                children: []
              }
            },
            {
              id: 'blake2b(data)',
              data: {
                name: 'child3',
                children: []
              }
            }
          ]
        }
      }
    ]
  }
}

I have been grappling with this issue for several hours now. While I believe there may be a straightforward solution, I am struggling to discover it. My knowledge of tree traversals is limited which has led me to dedicate most of my Sunday researching this topic without finding a resolution. Any assistance or guidance would be greatly appreciated.

Answer №1

Here is a stylish solution for you to refer back to in the future.

/**
 * This function walks through the tree, starting from the leaf node and moving upwards.
 * @param ops 
 */
export async function walkTheTreeFromLeafAndMakeChanges (ops: sto[]): Promise<stoWithIds[]> {
  async function visitNode (node: sto): Promise<stoWithIds> {
    async function visit (node: <storong>sto</strong>): Promise<<strong>stoWithIds</strong>> {
      // Using _unusedWithCamelCase
      const { children: _unusedChildren, ...rest } = node

      const newNode: <strong>stoWithIds</strong> = { id: '', data: { ...rest, children: [] } }

      // Executing leaves first, then same level leaves
      newNode.data.children = await Promise.all(
        node.children.map(async o => await visitNode(o))
      )

      return { id: blake2b(newNode), data: newNode.data }
    }

    return await visit(node)
  }

  const t = await Promise.all(
    ops.map(async o => {
      return await visitNode(o)
    })
  )
  // console.log('END', JSON.stringify(t))
  return t
}

This information is shared with hope that it can be of use to those exploring the online realm.

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

Limit function parameters to only accept values with matching keys

I am relatively new to using TypeScript and am currently working on a project that involves handling various shapes of data from different sources. My goal is to pass this data to different aggregator classes, with one aggregator class corresponding to eac ...

Angular asynchronous operations are failing to complete within the specified time frame

Observations suggest that Angular's async from @angular/core/testing is not properly resolving timeouts in tests when a beforeEach contains async as well. Sadly, the bug cannot be replicated on Plunkr or JSFiddle platforms. To reproduce this issue ea ...

Tips for importing a .geojson document in TypeScript using webpack?

I am trying to extract data from a .geojson file but faced some challenges while attempting two different methods: const geojson = require('../../assets/mygeojson.geojson'); The first method resulted in an error message stating: Module parse f ...

Trouble arises in TypeScript when defining a class - SyntaxError crops up

When I try to declare a class, I encounter an error: // The code below is from my test1.ts file class WDesign { wModel: string; wQuer: string; } let logWDesign = (wd : WDesign) => { console.log(wd.wModel + " " + wd.wQuer); } let wd1 : WDe ...

In Angular 5, a variable's value becomes undefined once it is subscribed to outside of its assigned

I keep encountering an undefined value when trying to assign the subscribed value to a variable in my code snippet below. service.ts getIpAddress() : Observable<any> { return this.http .get(this.Geo_Api) .map((response: ...

Is it possible to access the generic type that a different generic type inherits in TypeScript?

I've developed an interface specifically designed for types capable of self-converting to IDBKey: interface IDBValidKeyConvertible<TConvertedDBValidKey extends IDBValidKey> { convertToIDBValidKey: () => TConvertedDBValidKey; } My goal n ...

Can a library be developed that works with both Java and JavaScript/TypeScript?

I specialize in Angular development. Our front- and backend both contain specialized calculation methods that work like magic. Although the classes are the same, any bugs found in the calculations have to be fixed separately in two different projects. Is ...

Develop a flexible axios client

I have a basic axios client setup like this: import axios from "axios"; const httpClient = axios.create({ baseURL: "https://localhost:7254/test", }); httpClient.interceptors.request.use( (config) => config, (error) => Prom ...

What is the best way to combine individual function declarations in TypeScript?

In my project, I am currently developing a TypeScript version of the async library, specifically focusing on creating an *-as-promised version. To achieve this, I am utilizing the types provided by @types/async. One issue I have encountered is that in the ...

What causes TypeScript to automatically infer a default property when dynamically importing a JavaScript file that lacks a default export?

While dynamically importing a javascript file that exports multiple functions (without a default export), I encountered this issue: const sayHi = import('./sayHi.js') I was expecting the type of sayHi to be Promise<{name1: function, name2: fu ...

Unable to use console log in shorthand arrow function while working with Typescript

When debugging an arrow function in JavaScript, you can write it like this: const sum = (a, b) => console.log(a, b) || a + b; This code will first log a and b to the console and then return the actual result of the function. However, when using TypeSc ...

Gathering the output from every function within an array of functions

I've searched extensively for a solution to this dilemma, but have had no luck so far. Therefore, I am turning to the community for help. Please feel free to direct me to any existing similar queries. My challenge involves working with an array of fu ...

Module 'next-intl/client' cannot be located

When I run npm test, I encounter the following error: 'next-intl/client' module not found jest.mock( | ^ 22 | 'next-intl/client', 23 | (): Record<string, unknown> => ({ 24 | usePathname: ...

What is the best way to pass a value to a modal and access it within the modal's component in Angular 8?

How can I trigger the quickViewModal to open and send an ID to be read in the modal component? Seeking assistance from anyone who can help. Below is the HTML code where the modal is being called: <div class="icon swipe-to-top" data-toggle="modal" da ...

A guide on implementing RxJS Observables to target a specific DIV element

Currently, I am working with Angular 2. At the moment, I have been using this method to select a specific DIV element: <div #aaa> </div> @ViewChild('aaa') private aaa: ElementRef; ngAfterViewInit() { let item = this.aaa.nativeEle ...

Developing an npm library with ReactJs: A step-by-step guide

As a newcomer to React, I am eager to create my own npm library in ReactJS. Taking inspiration from my existing React project, the goal is to transform it into a package (or library) that can be easily integrated into other projects. This means allowing ...

Exploring the latest upgrades in React 18 with a focus on TypeScript integration

I am currently working on a complex TypeScript project with React and recently made the decision to upgrade to the new version of React 18. After running the following commands: npm install react@18 npm install react-dom@18 npm install @types/react-dom@18 ...

Understanding Typescript event handling in React

Encountering issues when attempting to build my React/Typescript app using the MouseEvent type in an event handler: private ButtonClickHandler(event: MouseEvent): void { ... } The error message received is as follows: error TS2322: Type '{ onCl ...

Using both Typescript and Javascript, half of the Angular2 application is built

My current project is a large JavaScript application with the majority of code written in vanilla JavaScript for a specific platform at my workplace. I am looking to convert this into a web application that can be accessed through a browser. I believe thi ...

Unable to extract numerical value from object using Dropdown (Angular 4)

When I retrieve data from an API, everything works smoothly except when I try to bind my JSON option number value into the [value] tag. Here's an example: SUCCESSFUL (data retrieved from API is selected in the option) <select [(ngModel)]="data.fr ...