hanenbro
hanenbro

Reputation: 604

Using an object as a dictionary with arrays as keys in JS

I'm trying to treat a JS object as a dictionary, and I want to use a pair of values (one literal value, one other object) as a single key, which I've been putting in array form, without success. The problem is that only the literal value is working to differentiate the keys, as the following snippet illustrates:

var dictionary = {};

var keyOne = { blah:1 };
var keyTwo = { blegh:2 };

var keyArrayOne = [keyOne, "label"];
var keyArrayTwo = [keyTwo, "label"];

dictionary[keyArrayOne] = "some data";

console.log(dictionary[keyArrayTwo]);    //Console returns 'some data'

I know I can use an array in place of my dictionary object, and just iterate through and compare, but was hoping to take advantage of the quicker look-up.

For more info, I won't know anything about the object that constitutes the first element of the key (it can be anything), but the second part is always a string.

Is there any way to achieve what I'm after?

Upvotes: 1

Views: 6657

Answers (1)

emou
emou

Reputation: 189

These might be helpful:

https://stackoverflow.com/a/10893426/1090464

https://stackoverflow.com/a/10908885/1090464

  • Keep in mind JSON.stringify won't work for circular objects. Also that method assumes JSON.stringify returns the object properties in the same order (see comments in the first link and https://stackoverflow.com/a/17459406/1090464).

  • The other method works if you're not concerned you're modifying the objects that are being passed in; and you will be doing the lookup using the exact same object instance, because using another instance with the same value won't work. Also, in your case the the get/put functions will be a bit different, maybe something like this:

    put: function(obj, label, value) {
        obj.__hash_id = this.nextId();
        this.hash[[obj.__hash_id, label]] = value;
    }
    
    get: function(obj, label) {
        return this.hash[[obj.__hash_id, label]];
    }
    
  • Another approach could be to use the labels as keys, and let the value be an array of [objectPartOfKey, value], through which you search linearly (just like a bucket in a hash table). This might still be faster than linear search in an array of [label, object] pairs if the number of objects per label is "small" relative to the total number of objects.

That being said, you might want to measure the performance hit first before optimizing your original code to make sure it is worth it.

Upvotes: 1

Related Questions