Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript map with two values in the key

Tags:

javascript

I have 3 dropdowns on my page, the options in the 3rd dropdown depend on the choices in the first two dropdowns.

So I am wondering if there is a way to implement a map in javaScript with a 2-dimensional key? Like <Key1, Key2> -> Value.

I think an easy way is to concatenate two keys into one string. Is there any way that is more decent?

Thanks.

like image 807
nababa Avatar asked Dec 21 '11 19:12

nababa


5 Answers

You can set a key as an array. Just create your array [key1, key2]; Then set that value as your key and relate it to your value.

obj[[key1,key2]] = "my value";

Here is a jsFiddle http://jsfiddle.net/TwQLW/

like image 142
Keith.Abramo Avatar answered Oct 22 '22 18:10

Keith.Abramo


I was looking for a similar data structure, but could not find. I have been working with TypeScript, so I have developed a solution using TypeScript.

export class TwoMapKey<T> {
    private __map__: object;

    constructor() {
        this.__map__ = new Object();
        this.get = this.get.bind(this);
        this.set = this.set.bind(this);
        this.remove = this.remove.bind(this);
        this.keys = this.keys.bind(this);
        this.nestedKeys = this.nestedKeys.bind(this);
        this.clear = this.clear.bind(this);
    }

    public get(key: string, nestedKey: string): T {
        if (!this.__map__[key] || this.__map__[key] && !this.__map__[key][nestedKey])
            return;

        return this.__map__[key][nestedKey];
    }

    public set(key: string, nestedKey: string, value: T): void {
        if (!this.__map__[key]) {
            this.__map__[key] = new Object();
        }

        Object.defineProperty(this.__map__[key], nestedKey, { value: value, configurable: true, enumerable: true });
    }

    public remove(key, nestedKey): void {
        if (!this.__map__[key]) {
            return;
        }

        delete this.__map__[key][nestedKey];
    }

    public keys(): string[] {
        return Object.getOwnPropertyNames(this.__map__);
    }

    public nestedKeys(): Array<string[]> {
        return Object.getOwnPropertyNames(this.__map__).map(key => Object.keys(this.__map__[key]));
    }

    public clear(): void {
        Object.getOwnPropertyNames(this.__map__).forEach(property => {
            delete this.__map__[property];
        });
    } }

You can simply create a map with two keys as below:

let twoKeyMap = new TwoKeyMap<any>();
twoKeyMap.set('mainKey1', 'nestedKey1', {value: 'value'});

Its not as efficent as a HashMap. You should be able to convert the same in ES6 or ES5 easily.

like image 28
Rahul Sethi Avatar answered Oct 22 '22 19:10

Rahul Sethi


I created a generic data structure for this purpose as I had a similar problem:

https://github.com/vikashmadhow/map

I know quite some time has passed since this question was asked; hopefully this might be of help to others.

like image 38
Vikash Madhow Avatar answered Sep 20 '22 17:09

Vikash Madhow


You could have an object that contains more objects:

var options = {
    'option 1': {
        'option 1.1': [
            'option 1.1.1',
            'option 1.1.2',
            'option 1.1.3',
            'option 1.1.4'
        ],
        'option 1.2': [
            'option 1.2.1',
            /* etc. */
};

Then, you would access the options for the third dropdown as options[firstSelectedValue][secondSelectedValue].


EDIT: Here's a demo, too, using some new features that you may need to implement if you're browsing using Internet Explorer 8 or lower :)

like image 5
Ry- Avatar answered Oct 22 '22 20:10

Ry-


What is wrong with concatenating the two keys? All you need is to be sure, that the concatenated keys are unique, and I guess that this can easily be achieved by separating the two values with a character that is not used by any of the two keys.

like image 2
Jan Aagaard Avatar answered Oct 22 '22 18:10

Jan Aagaard