Tips for guaranteeing type checking a function will yield the identical reference for identical arguments

I am working with a variety of functions that interact with each other to generate new objects. Some functions produce sets composed of the return values of these other functions. My goal is to ensure that I retrieve the same object reference from these functions when provided with identical arguments, in order to prevent duplicates within the set.

type A = { a: number, b: number };

type A2 = { c: A, d: A };

function makeA(a: number, b: number): A {
    return {
        a, b
    };
}

function makeA2(c: A, d: A): A2 {
    return { c, d };
}

console.log(makeA(2, 3) === makeA(2, 3)); // Desired outcome is true

let res = [
makeA2(makeA(1,1), makeA(1,2)),
makeA2(makeA(1,1), makeA(1,2)),
makeA2(makeA(1,1), makeA(1,2)),
makeA2(makeA(1,1), makeA(1,2))
];

console.log(new Set(res)); // Expected result is a single element in this list

I've attempted to create a utility function named DB which maintains a map linking the two arguments taken by the functions to the corresponding return value, and then retrieves the cached value on subsequent calls. However, I am still encountering duplicate entries. It's possible that I may need to wrap certain functions or that there is a fundamental flaw in my approach.

Answer №1

Indeed, it is essential to cache the return values of makeA and makeA2 in order to ensure consistency when the same inputs are provided. There are various methods to accomplish this task, but the key is to accurately identify "the same inputs" in a reliable manner.

One potential approach involves maintaining separate caches for each function. Although there is some repetition in the code, there exists an opportunity to optimize it by reducing redundancy while still achieving the desired outcome:

function makeA(a: number, b: number): A {
    const key = a + ";" + b;
    let ret = makeA.cache.get(key);
    if (!ret) {
        ret = { a, b };
        makeA.cache.set(key, ret);
    }
    return ret;
}
makeA.cache = new Map<string, A>();

function makeA2(c: A, d: A): A2 {
    const key = c.a + ";" + c.b + ";" + d.a + ";" + d.b;
    let ret = makeA2.cache.get(key);
    if (!ret) {
        ret = { c, d };
        makeA2.cache.set(key, ret);
    }
    return ret;
}
makeA2.cache = new Map<string, A2>();

In the case of makeA, the identification of "the same inputs" involves concatenating the string representations of the two numeric inputs with a semicolon as a separator to generate a lookup key of type string. For makeB, a similar process is applied considering the four distinct numeric sub-properties. While technically one could use the "identities" of the c and d objects exclusively, this method can be cumbersome and may not yield substantial benefits. Ultimately, maintaining object instances using a Map<A, Map<A, A2>> structure can prove challenging and often unnecessary. In scenarios where

makeA2({a: 1, b: 2}, {a: 1, b: 2})
and
const a = {a:1, b:2}; makeA2(a, a)
might produce identical results, the goal is typically to avoid creating excessive instances.

The approach involves checking the cache for each key; if present, the cached value is retrieved. Otherwise, a new entry is created at that specific key for future reference.


Verification of functionality:

console.log(makeA(2, 3) === makeA(2, 3)); // true

let res = [
    makeA2(makeA(1, 1), makeA(1, 2)),
    makeA2(makeA(1, 1), makeA(1, 2)),
    makeA2(makeA(1, 1), makeA(1, 2)),
    makeA2(makeA(1, 1), makeA(1, 2))
];

console.log(new Set(res).size); // 1

Satisfactory results confirmed.

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

Cannot assign value to property x on y as it is not an object - dealing with Multidimensional Arrays

I'm experimenting with creating a multidimensional array that looks like this: var minutes = []; for (let i = 1; i < 10; i++) { minutes.push(i); } var works = [{ startTime: 80000, endTime: 150000 }, { startTime: 200000, endTime: 400000 ...

How can I implement Google Analytics Event tracking for all <audio> tags using Javascript?

I am looking to implement a Google Analytics Event for all audio tags on my website. Currently, I have a script that targets audio tags with a specific class: <script> /* a test script */ $(function() { // Execute function when any element with t ...

Discover the secrets to replicating the mesmerizing horizontal scrolling menu akin to the

What is the most effective way to create a horizontal menu similar to the innovative Google picture menu? Could someone kindly share their knowledge and provide the code for achieving the same outcome? ...

Utilizing Props in Next.js with a Form Component

Currently, I am diving into the world of Nextjs and facing a challenge in passing a variable through a form component, and then further through its server action component. (I believe this is referred to as prop drilling, and I'm exploring if there&ap ...

Guide on accessing mobile information and sim card details with Ionic 3 and Cordova on Android devices

Just started using Ionic and I'm looking for guidance on how to retrieve mobile and sim details with Ionic 3 and Cordova for Android. Any help is greatly appreciated in advance! ...

Enhancing Javascript arrays with powerful functional programming methods

I'm trying to figure out the functionality of this code. Although I am familiar with the reduce and concat functions in Array, I am having trouble grasping how this code operates at first glance: var arrays = [[1, 2, 3], [4, 5], [6]]; console. ...

Trouble arises when displaying data using AngularJS in an HTML environment

I'm currently facing a challenge understanding where I went wrong in my code. My goal is to display the initial array values in the table data, but so far, I haven't had much success. Here is the HTML section of the code; <body ng-controller ...

Mapping nested array of references in Angular Firestore

I am working with a collection called A, which contains documents that reference other documents in collection B. https://i.sstatic.net/C1HtT.png When fetching my A documents from the service, I receive an array of objects that are not usable. However, I ...

Workers in Async.js queue failing to complete tasks

Creating a job queue to execute copy operations using robocopy is achieved with the following code snippet: interface copyProcessReturn { jobId: number, code: number, description: string, params: string[], source: string, target: s ...

Expanding a Material UI Accordion does not cause the surrounding content to shift or move

I'm currently designing a User Interface for a web application that allows users to have multiple projects open simultaneously. To achieve this, I decided to use an accordion as the logical component in the left navigation bar. The reason behind this ...

Ways to identify when a specific react component has been clicked

Currently working on developing a klondike game with 4 empty stacks at the start of the game. The initial page layout resembles the first image provided in the link. I am facing an issue where I cannot determine which component was clicked when clicking on ...

No acknowledgment from command

Why doesn't the bot respond when I run this command? There are no errors. Do I have the role that matches in r.id? client.on('message', async message => { // Check if the user has a role with an id if(message.author.bot) return; ...

Relocate the number of records displayed per page next to the pagination controls in datatables

Currently, I am utilizing datatables to create tables effectively using their provided example. However, I am encountering difficulty in moving the "records per page" element, which is contained within a "span6" class of bootstrap. I understand that this ...

Encountering a "type" property error with the cordova network plugin due to undefined value

During the development of my Android application using Cordova and Ionic framework, I encountered an issue with the network plugin from this source (https://github.com/apache/cordova-plugin-network-information). After the device ready alert triggers, I re ...

Setting limits to disable or remove specific times from the time picker input box in Angular

I'm having trouble with a time input box. <input type="time" min="09:00" max="18:00" \> Even though I have set the min and max attributes to values of 09:00 and 18:00 respectively, it doesn't seem to be working properly. I want to ...

Is it not possible to unselect the radio button?

I've been trying to implement a jQuery solution that allows radio buttons to be deselected, but I'm encountering difficulties with the prop function. Every time this code is executed, my condition ($(e.currentTarget).prop('checked')) al ...

The static HTML export encountered an issue: 'Error: Server Component type not supported: {...}'

Encountered an error while attempting to export a next js blog page to static html. My goal is to obtain the basic html structure with tailwind CSS from this blog template. Following the instructions on the next js documentation, I made changes to module ...

What is the best method for retrieving data from a specific collection in MongoDB?

Within the code snippet below, on the 4th line, 'Messages' is the name of my MongoDB collection that I created in another file. When I attempt to retrieve data from this collection, no errors occur. However, when I specify the name of a differen ...

Filter an array of objects by using another array that contains duplicate keys

I am facing an issue with filtering objects in an array based on another array of values. Here is the scenario: const data = [ { id: 1, name: 'Name1', encryptionKey: 'AAA' }, { id: 2, name ...

Array elements being listed

I recently encountered an issue while trying to store values in a JavaScript object notation. After some programming, I managed to store all occurrences in a string separated by commas. However, when the term I'm looking for is an array, I receive [ob ...