Are there more efficient alternatives to utilizing arrays and index-based functions for storing in-memory data in TypeScript?

Is there a more efficient method for storing and retrieving data besides relying on Array index-based calls?

For instance:

export interface EntityInterface {
    id: number;
    name: string;
    age: number;
}

export class ClassName {
    entities: EntityInterface[] = [];

    temporaryIndex: number = 0;

    createEntity(name: string, age: number) {
        const temporaryId = ++this.temporaryIndex;

        this.entities.push({
            id: temporaryId,
            name: name,
            age: age
        });
    }

    getEntityById(id: number): number | undefined {
        const entityIndex = this.entities.findIndex((entity) => entity.id === id);
        if (entityIndex === -1) {
            return;
        }

        return entityIndex;
    }

    getEntityName(id: number): string | undefined {
        const index = this.getEntityById(id);
        if (! index) {
            return;
        }

        return this.entities[index].name;
    }
}

It's important to note that utilizing an external database isn't essential in this scenario since data loss upon application shutdown is not a concern.

Answer №1

When looking up a value by a numeric key in TypeScript (and consequently in JavaScript), it is advisable to utilize a data structure specifically designed for this purpose.

In plain JavaScript objects, this functionality is built-in; however, in TypeScript, you can define a numeric index signature for an object:

class ClassName {
    entities: { [k: number]: EntityInterface | undefined } = {};

    temporaryIndex: number = 0;

    createEntity(name: string, age: number) {
        const temporaryId = ++this.temporaryIndex;
        this.entities[temporaryId] = {
            id: temporaryId,
            name: name,
            age: age
        };
    }

    // the utility of this method is limited
    getEntityById(id: number): number | undefined {
        return this.entities[id] ? id : undefined
    }

    getEntityName(id: number): string | undefined {
        return this.entities[id]?.name;
    }
}

Alternatively, you can utilize a JavaScript Map, specifying that it holds EntityInterface values paired with number keys:

class ClassName {
    entities = new Map<number, EntityInterface>()

    temporaryIndex: number = 0;

    createEntity(name: string, age: number) {
        const temporaryId = ++this.temporaryIndex;
        this.entities.set(temporaryId, {
            id: temporaryId,
            name: name,
            age: age
        });
    }

    // the utility of this method is limited
    getEntityById(id: number): number | undefined {
        return this.entities.has(id) ? id : undefined
    }

    getEntityName(id: number): string | undefined {
        return this.entities.get(id)?.name;
    }
}

Both approaches yield similar results, especially when compared to iterating through an array. Refer to Map vs Object in JavaScript and the MDN documentation on Map vs Object for guidance on selecting the most suitable option.

In both implementations, the function getEntityById(id) now returns either the input or undefined, rendering it less useful. Instead, directly access this.entities using id as the key and handle a potentially undefined outcome.

Playground link to code

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: Dealing with a deadlock error triggered by a single query following the

I have a question about managing a query that runs across multiple micro-services, which can sometimes lead to deadlocks. const handleExecution = async (id: number): Promise<boolean> => { try { const query = ` UPDATE articles a1 ...

A single element containing two duplicates of identical services

I am encountering an issue with my query builder service in a component where I need to use it twice. Despite trying to inject the service twice, it seems that they just reference each other instead of functioning independently, as shown below: @Component( ...

Contact the help desk and receive information that is currently unknown

There are a few issues that I'm struggling to resolve. I am utilizing SwaggerService to fetch data, but the response is coming back as undefined. import {SwaggerService} from '../../services/swagger.service'; export class TestComponent im ...

Is there a way to inform TypeScript that the process is defined rather than undefined?

When I execute the code line below: internalWhiteList = process.env.INTERNAL_IP_WHITELIST.split( ',' ) An error pops up indicating, Object is possibly undefined. The env variables are injected into process.env through the utilization of the mod ...

What steps should I take to resolve the error message "ESLint encountered an issue determining the plugin '@typescript-eslint' uniquely"?

Struggling to enable eslint linting in an ASP.NET Core MVC project that incorporates React.js and typescript? I'm facing a tough challenge trying to resolve the error mentioned above. In my setup, I'm using Visual Studio 2022 Community Edition 1 ...

Encountering an issue with applying D3 fill to a horizontal stacked bar chart in Angular using TypeScript. When using .attr("fill", ..) in VSC, an error stating "No overload matches this call" is displayed

My goal is to create a stacked horizontal bar chart in d3, and I've been following the code example provided here. To showcase my progress so far, I have set up a minimal reproduction on stackBlitz which can be found here. While there are no errors ...

Incorporating CodeMirror into Angular2 using TypeScript

I've been working on integrating a CodeMirror editor into an Angular2 project, but I'm encountering some issues with the instantiation of the editor. Here is my code snippet: editor.component.ts import {Component} from 'angular2/core' ...

Exploring the use of MockBackend to test a function that subsequently invokes the .map method

I've been working on writing unit tests for my service that deals with making Http requests. The service I have returns a Http.get() request followed by a .map() function. However, I'm facing issues with getting my mocked backend to respond in a ...

Strategies for implementing searchbar filtering in Ionic3 and Angular5 data manipulation

I'm having trouble displaying product names on my search.html page based on the search bar input. I've tried using the Ionic searchbar component but it's not working. Can anyone help me with this issue? If there's an alternative solutio ...

Tips for defining the type of any children property in Typescript

Currently, I am delving into Typescript in conjunction with React where I have a Team Page and a slider component. The slider component is functioning smoothly; however, my goal is to specify the type of children for it. The TeamPage import react, { Fragm ...

The 'filter' attribute is not found in the 'ContextProps' type

I am currently working on a project in Next.js 13 where I am trying to render card items conditionally based on their status. The TypeScript version being used is "5.2.2". However, I encountered an error that says: Property 'filter' does not exis ...

Karma Jasmin is puzzled as to why her tests are failing intermittently, despite the absence of any actual test cases

In this snippet, you will find my oninit method which I am instructed not to modify. ngOnInit(): void { this.setCustomizedValues(); this.sub = PubSub.subscribe('highlightEntity', (subId, entityIdentifier: string) => { ...

Issue with exporting Typescript React component

Despite searching for answers, none of the related questions have been helpful... My goal is to export React components from a TypeScript library that I plan to publish on npm. For testing purposes before publishing, I am utilizing npm link. The structu ...

TypeScript: "Implementing" methods. The organized approach

Currently, I am developing a middleware class for Express. Before delving into the details of the class, it's important to note that I will be injecting the middleware later by creating an instance of my "Authenticator" class and then using its method ...

The supabase signup function keeps showing me the message "Anonymous sign-ins are disabled." Can anyone help me understand why this is happening?

I'm currently in the process of setting up authentication in Next.js with supabase, but encountering an issue when attempting to execute the signUp function. The error message I'm seeing is: Anonymous sign-ins are disabled Below is the snippet o ...

Error Message: The specified HTML element already contains two instances of the WebViewer, leading to a conflict in PDFTron React TypeScript Next

Having some trouble using pdftron with my docx editor. I can use the editor fine, but keep encountering an error like the one shown below: https://i.stack.imgur.com/OnJxE.png https://i.stack.imgur.com/l9Oxt.png Here is a snippet of my code: wordeditor.t ...

Establish a connection between MongoDB and the built-in API in Next.js

I've been working on integrating a MongoDB database with the Next.js built-in API by using the code snippet below, which I found online. /api/blogs/[slug].ts import type { NextApiRequest, NextApiResponse } from 'next' import { connectToData ...

Solve the TypeScript path when using jest.mock

I am currently in the process of adding unit tests to a TypeScript project that utilizes compilerOptions.paths. My goal is to mock an import for testing purposes. However, I have encountered an issue where jest is unable to resolve the module to be mocked ...

What is the reason that Gatsby's arrow function is unable to access a value from props that is calculated from a promise?

Could someone shed light on why the key value is showing as undefined within the arrow function: // in parent component const Parent = () => { const [key, setKey] = useState<string>(); // this contains an expensive function we on ...

Using Typescript to implement a conditional return type and ensuring that the value types are consistent together

I am working with a useSelectedToggle hook that helps in connecting the UI state to the open/closed status of a dialog where it will be displayed. The toggle defines the value as (T) when it is open, and null when it is closed. How can I enforce stricter ...