What is the best way to store a set of tuples in a collection so that each tuple is distinct and

I am working with TypeScript and aiming to create a collection of unique objects, each with distinct properties. The combinations of these properties within the collection must be one-of-a-kind.

For example, the following combinations would be considered valid:

[
    [ 1, 2 ],
    [ 2, 1 ],
]

However, attempting to add a duplicate combination such as [ 1, 2 ] would result in a "key already exists" error.

It's worth noting that my query assumes the presence of 3 keys representing the "composite key," but I am open to more flexible solutions if they exist.

In an attempt to address this challenge, I developed my own JavaScript-based "map-like" structure as a demonstration:

class MyCollection {
  constructor() {
    this.items = [];
  }

  add(firstTupleItem, secondTupleItem, thirdTupleItem) {
    if (this.has(firstTupleItem, secondTupleItem, thirdTupleItem)) {
      console.log(`ERR: Combination of [${firstTupleItem}, ${secondTupleItem}, ${thirdTupleItem}] already exists!`);

      return;
    }

    console.log(`Added combination of [${firstTupleItem}, ${secondTupleItem}, ${thirdTupleItem}]`);

    this.items.push([firstTupleItem, secondTupleItem, thirdTupleItem]);
  }

  has(firstTupleItem, secondTupleItem, thirdTupleItem) {
    return this.items.some(item =>
      item[0] === firstTupleItem &&
      item[1] === secondTupleItem &&
      item[2] === thirdTupleItem);
  }
}

const myCollection = new MyCollection();

/* passes as expected */

myCollection.add(1, 2, 3);
myCollection.add(2, 1, 3);
myCollection.add(3, 1, 2);
myCollection.add(1, 3, 2);

/* fails as expected */

myCollection.add(1, 2, 3);

console.log(myCollection.items);

While using a map could potentially offer improved efficiency, there may be concerns regarding the utilization of the value side. As an alternative concept, consider the following:

class MyCustomMap extends Map<[number, number, number], [number, number, number]> {
    addItem(item: [number, number, number]) {
        super.set(item, item);
    }
}

Is it necessary for me to create such a collection structure from scratch, or are there alternative, more efficient solutions available? (particularly within the context of TypeScript)

Answer №1

Looking for a way to store unique values in JavaScript? Consider using a Set. This data structure ensures that each value is unique within the collection. However, it's important to note that the default equality check used by Set might not always meet your requirements. It follows the "same-value zero" equality rule, which behaves differently for objects like arrays compared to primitives like strings and numbers.

const a = [1, 2];
const b = [1, 2];
console.log(a === b); // false

const c = a;
console.log(a === c); // true

To customize the equality check for objects, you'll need to implement your own function. One approach is to convert objects to a primitive key using a method like JSON.stringify(). This ensures that two arrays are considered equal if their contents match.

Here's an example of how you can create a custom collection called MyCollection:

class MyCollection {
    private items: Map<string, Props> = new Map();
    add(...props: Props) {
        this.items.set(propsToKey(props), props);
        return this;
    }
    // Additional methods for managing the collection...
}

By implementing your custom equality function and using it in a Set or Map, you can ensure that values are uniquely stored based on your defined criteria.

Try out the code in the TypeScript playground.

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

Ways to extract particular keys from a JSON array?

I am receiving an array of JSON objects in my response. {"took":0,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{" ...

An easy way to insert a horizontal line between your text

Currently, I have two text responses from my backend and I'm considering how to format them as shown in the design below. Is it possible to automatically add a horizontal line to separate the texts if there are two or more broadcasts instead of displa ...

Prevent the function from running more than once

I need a specific function function toDiv() { $(".wrap"))) $('.barfill').each(function(){ var width=$(this).data('width'); $(this).animate({ width: width }, 500); var $perctext = $('<div>', ...

Integrate a resizable sidebar on the webpage's right side that dynamically adjusts the layout

As I develop a Chrome Extension, my goal is to incorporate a sidebar into all webpages without overlapping the existing content. The sidebar should be placed beside the content, effectively reducing the width of the body of the webpage to the initial width ...

Updating a deeply nested value with React's setState

Dealing with a deeply nested object in my React state has been quite the challenge. The task at hand is to modify a value within a child node. Fortunately, I have already identified the path leading to the node that needs updating and I am utilizing helper ...

Unable to sign up for WordPress function

I'm having trouble getting my function registered properly in WordPress, no matter how many times I try. So far, here's what I've done: Inserted code into themes functions.php function test_my_script() { wp_register_script( 'custom-s ...

How come Typescript claims that X could potentially be undefined within useMemo, even though it has already been defined and cannot be undefined at this stage

I am facing an issue with the following code snippet: const productsWithAddonPrice = useMemo(() => { const addonsPrice = addonsSelected .map(id => { if (addons === undefined) { return 0} return addons.find(addon => addo ...

How can CSS and JavaScript be used to strategically position two upright images next to each other within a dynamically resizing container?

Looking for a way to display two portrait images side by side within a flexible container with 100% width? The challenge I'm facing is accommodating varying widths of the images while ensuring they are the same height. <div class="container"> ...

Creating Custom Filters in Angular using Functions

Attempting to filter ng-repeat using a function instead of an actual filter has presented some challenges. The code snippet below demonstrates the attempt: <tr ng-repeat="(key, value) in dataObj| filter:dataFilter"> The intention is to define dataF ...

How to prevent panning on mobile devices in Three.js using Javscript?

Currently working on my 3D project using three.js and everything is running smoothly on my laptop. I'm utilizing OrbitControls for camera movement, but I have disabled right-click panning to only allow camera rotation. However, when testing on a mobil ...

REST operations are malfunctioning while other methods are functioning correctly

It's quite strange, but I'm clueless about what could be causing this chaos. Here's the code snippet I'm working with: var express = require('express'); var router = express.Router(); var mongoose = require('mongoose&ap ...

What is the best way to effectively use combinedLatestWith?

https://stackblitz.com/edit/angular-ivy-s2ujmr?file=src/app/country-card/country-card.component.html I am currently working on implementing a search bar in Angular that filters the "countries$" Observable based on user input. My approach involves creatin ...

Error: JSON encountered circular structure when attempting to serialize an object of type 'ClientRequest' with a property 'socket' that references an object of type 'Socket'

Encountering an error while attempting to make a POST request to my TypeORM API using axios: TypeError: Converting circular structure to JSON --> starting at object with constructor 'ClientRequest' | property 'socket' -&g ...

Tips on handling multiple Redux toolkit CreateApi interceptors

I came across this solution here for implementing a reAuth baseQuery in Redux Toolkit. I have several backend services that all use the same refresh token concept. Is there a way to create a single baseQueryAuth function that can be used by multiple creat ...

use the fetch api to send a url variable

I'm struggling to pass a URL variable through the API fetch and I can't seem to retrieve any results. As a newcomer to Javascript, any help is greatly appreciated. //Get IP address fetch('https://extreme-ip-lookup.com/json/') .then(( ...

Tips for adding event listeners to dynamically-loaded content using AJAX

I need help with the following code snippet: $("#contantainer").load("some_page.txt"); Inside some_page.txt, I have the following content: <div class="nav"> <ul id="nav_ul"> <li><a class="nav_a" href="#home" id="home"> ...

Issue: React error message indicates that the .map() function is not recognized. The API response is in the form of an object, making

As a newcomer to REACT.JS, I am currently facing the challenge of extracting data from an API for my project. Utilizing "Axios" for sending the get request, I have encountered a situation where the response comes back as an array in one API and as an objec ...

The alignment issue persists in HTML/CSS despite troubleshooting efforts

I am facing a challenge while attempting to center text within a modal window, despite my efforts the text remains uncentered. This is my HTML code: <div ng-init="modalCompassDir()"> <div class="myModal"> <img class='floor ...

Next.js encountered an issue when trying to read properties of null, specifically the 'push' property, resulting in a TypeError

I am utilizing the sweetalert2 library for displaying popups: export default function Home() { const MySwal = withReactContent(Swal) useEffect(() => { MySwal.fire({ showConfirmButton: false, customClass: { ...

CAUTION: Attempted to initialize angular multiple times...all because of jQuery...such a puzzling issue, isn

I am attempting to comprehend the situation at hand. The warning is clear, and I acknowledge that in my application, with the provided code and structure, the ng-view runs twice ('test' is logged twice in the console, indicating that angular is l ...