Search code examples
node.jsassociative-array

Associative arrays in Node JS for a list of subscribers


I need to create, in Node JS, a list of "subscribers" which will provide a device (string) for which they want to receive notifications when there is new data from, and the IP and Port (both strings) to forward the data. The list should be unique; i.e., there should only be just one combination of (device, IP, Port) in the list. I also need to efficiently get a sub-list of IP/Port of subscribers when data come from a device, to know where to forward the data to.

In other languages, I was using Associative Arrays for this (with Unique index), so using something like this;

subscribers[device] = (IP,Port)

solved the problem. So when new data comes from a device, filtering the array with the device index, gives me a list of subscribers to forward the data to.

I'm wondering what is the best approach to implement this in Node JS. I was looking at Arrays, but I don't find Associative Arrays, and I'm not sure if another way would be a better approach...

Thanks in advance Gus


Solution

  • A simple solution that works for your use case is using a Map of Sets of strings, where you concat the IP address and port:

    const subscribers = new Map<string, Set<string>>();
    
    function addSubscriber(device: string, ip: string, port: number) {
        let set = subscribers.get(device);
        if (!set) {
            set = new Set<string>();
            subscribers.set(device, set);
        }
        // Lowercase in case your IP is an IPv6 and can have random upper/lower case
        set.add(`${ip.toLowerCase()}:${port}`);
    }
    
    const splitCombo = (combo: string): [string, number] => {
        const split = combo.split(':');
        return [split[0], parseInt(split[1])];
    };
    
    function getSubscribers(device: string): [ip: string, port: number][] {
        const set = subscribers.get(device);
        if (!set) return [];
        return Array.from(set).map(splitCombo);
    }
    

    written in TypeScript to show you the types

    Otherwise you'd need to create your own variant of an associated map/list. Still possible and maybe a lot of fun, but also a lot more complex than this simple variant. E.g. replace the Set<string> with a [string, number][] array, but then you'd have to manually check when adding a new pair if that pair is already present. Using a Set<string>, the .add will quite efficiently take care of this for you.