177

i need to make a dictionary in javascript like this

i dont remember the exact notation, but it was something like:

states_dictionary={ CT=[alex,harry], AK=[liza,alex], TX=[fred, harry] ........ }

is there such a thing in javascript?

6
  • 2
    See this question: stackoverflow.com/questions/130543/… Commented Aug 24, 2010 at 17:16
  • 7
    The answer you accepted is very wrong. Commented Aug 3, 2012 at 5:31
  • @EsbenSkovPedersen Which errors did you notice in that answer? Commented Sep 1, 2013 at 4:19
  • I see it is edited after I commented. It seems : was missing Commented Sep 2, 2013 at 11:34
  • 2
    Read most recent answer for ES6 Maps stackoverflow.com/a/32993723/1993919 (commenting for same reason it was posted) Commented Jun 21, 2016 at 9:24

7 Answers 7

194

This is an old post, but I thought I should provide an illustrated answer anyway.

Use javascript's object notation. Like so:

states_dictionary={ 
     "CT":["alex","harry"], 
     "AK":["liza","alex"], 
     "TX":["fred", "harry"]
};

And to access the values:

states_dictionary.AK[0] //which is liza

or you can use javascript literal object notation, whereby the keys not require to be in quotes:

states_dictionary={ 
     CT:["alex","harry"], 
     AK:["liza","alex"], 
     TX:["fred", "harry"]
};
Sign up to request clarification or add additional context in comments.

5 Comments

it's worth noting that the first example should yield the same object in both languages using exactly same syntax except the closing ';'. states_dictionary={ "CT":["alex","harry"], "AK":["liza","alex"], "TX":["fred", "harry"] }
I am more used to the literal object notation, since you access them in the same way what is the difference between the two?
@JohnDemetriou the main difference is javascript object notation keys must be strings (enclosed in double quotes " " ). The object notation is as seen in JSON for data interchage and was inspired by the literal object notation; it is worth noting that JSON is usually used in string context
Actually, Python allows statement-terminating semicolons, so the first example is completely valid both in Python and JavaScript
If the value comes from the user, then care needs to be taken to use Object.hasOwnProperty.call(dictionary, key) (otherwise the user can enter a value of valueOf and dictionary['valueOf'] returns the Object.valueOf() function belonging to the Object prototype which is probably not what your code would expect - potential bug or security issue). If the key is not a string type, then care needs to be taken, otherwise the implicit numeric and toString conversions will cause you problems. The ES6 Map type has been designed to provide extended functionality for dictionaries.
92

There were no real associative arrays in Javascript until 2015 (release of ECMAScript 6). Since then you can use the Map object as Robocat states. Look up the details in MDN. Example:

let map = new Map();
map.set('key', {'value1', 'value2'});
let values = map.get('key');

Without support for ES6 you can try using objects:

var x = new Object();
x["Key"] = "Value";

However with objects it is not possible to use typical array properties or methods like array.length. At least it is possible to access the "object-array" in a for-in-loop.

3 Comments

What about the performance? is looking up a key in an object constant time?
Since o["key"] is equivalent to o.key in Javascript the performance is almost the same. However performance depends on the Javascript Engine / Webbrowser. There are quite a lot differences between these, especially in the older versions.
ECMAScript 6 defines an official Map object (i.e. "There are no real associative arrays in Javascript" is now incorrect).
49

In ECMAScript 6, the official Map object has been introduced, which is a dictionary implementation:

let dict = new Map();
dict.set("foo", "bar");

//returns "bar"
dict.get("foo");

Unlike javascript's normal objects, it allows any object as a key using identity comparison:

let foo = {};
let bar = {};
let dict = new Map();
dict.set(foo, "Foo");
dict.set(bar, "Bar");

//returns "Bar"
dict.get(bar);

//returns "Foo"
dict.get(foo);

//returns undefined, as {} !== foo and {} !== bar
dict.get({});

There is no way to have a user defined key comparator, so if you do not desire identity comparison, you are still stuck with only using number or string keys like with a normal object.

1 Comment

Works for me, nice to use a cleaner ES6 method. Thank you! Follow up, de we know any way to "bulk set()", e.g. like python dict = { key: value)?
11

Have created a simple dictionary in JS here:

function JSdict() {
    this.Keys = [];
    this.Values = [];
}

// Check if dictionary extensions aren't implemented yet.
// Returns value of a key
if (!JSdict.prototype.getVal) {
    JSdict.prototype.getVal = function (key) {
        if (key == null) {
            return "Key cannot be null";
        }
        for (var i = 0; i < this.Keys.length; i++) {
            if (this.Keys[i] == key) {
                return this.Values[i];
            }
        }
        return "Key not found!";
    }
}


// Check if dictionary extensions aren't implemented yet.
// Updates value of a key
if (!JSdict.prototype.update) {
    JSdict.prototype.update = function (key, val) {
        if (key == null || val == null) {
            return "Key or Value cannot be null";
        }
        // Verify dict integrity before each operation
        if (keysLength != valsLength) {
            return "Dictionary inconsistent. Keys length don't match values!";
        }
        var keysLength = this.Keys.length;
        var valsLength = this.Values.length;
        var flag = false;
        for (var i = 0; i < keysLength; i++) {
            if (this.Keys[i] == key) {
                this.Values[i] = val;
                flag = true;
                break;
            }
        }
        if (!flag) {
            return "Key does not exist";
        }
    }
}



// Check if dictionary extensions aren't implemented yet.
// Adds a unique key value pair
if (!JSdict.prototype.add) {
    JSdict.prototype.add = function (key, val) {
        // Allow only strings or numbers as keys
        if (typeof (key) == "number" || typeof (key) == "string") {
            if (key == null || val == null) {
                return "Key or Value cannot be null";
            }
            if (keysLength != valsLength) {
                return "Dictionary inconsistent. Keys length don't match values!";
            }
            var keysLength = this.Keys.length;
            var valsLength = this.Values.length;
            for (var i = 0; i < keysLength; i++) {
                if (this.Keys[i] == key) {
                    return "Duplicate keys not allowed!";
                }
            }
            this.Keys.push(key);
            this.Values.push(val);
        }
        else {
            return "Only number or string can be key!";
        }
    }
}

// Check if dictionary extensions aren't implemented yet.
// Removes a key value pair
if (!JSdict.prototype.remove) {
    JSdict.prototype.remove = function (key) {
        if (key == null) {
            return "Key cannot be null";
        }
        if (keysLength != valsLength) {
            return "Dictionary inconsistent. Keys length don't match values!";
        }
        var keysLength = this.Keys.length;
        var valsLength = this.Values.length;
        var flag = false;
        for (var i = 0; i < keysLength; i++) {
            if (this.Keys[i] == key) {
                this.Keys.shift(key);
                this.Values.shift(this.Values[i]);
                flag = true;
                break;
            }
        }
        if (!flag) {
            return "Key does not exist";
        }
    }
}

The above implementation can now be used to simulate a dictionary as:

var dict = new JSdict();

dict.add(1, "one")

dict.add(1, "one more")
"Duplicate keys not allowed!"

dict.getVal(1)
"one"

dict.update(1, "onne")

dict.getVal(1)
"onne"

dict.remove(1)

dict.getVal(1)
"Key not found!"

This is just a basic simulation. It can be further optimized by implementing a better running time algorithm to work in atleast O(nlogn) time complexity or even less. Like merge/quick sort on arrays and then some B-search for lookups. I Didn't give a try or searched about mapping a hash function in JS.

Also, Key and Value for the JSdict obj can be turned into private variables to be sneaky.

Hope this helps!

EDIT >> After implementing the above, I personally used the JS objects as associative arrays that are available out-of-the-box.

However, I would like to make a special mention about two methods that actually proved helpful to make it a convenient hashtable experience.

Viz: dict.hasOwnProperty(key) and delete dict[key]

Read this post as a good resource on this implementation/usage. Dynamically creating keys in JavaScript associative array

THanks!

Comments

7

Use JavaScript objects. You can access their properties like keys in a dictionary. This is the foundation of JSON. The syntax is similar to Python dictionaries. See: JSON.org

1 Comment

"Watch" out! Object prototype methods like "watch" can bite you this way. Even if you don't have any of those, you'll at least have "constructor".
4

An old question but I recently needed to do an AS3>JS port, and for the sake of speed I wrote a simple AS3-style Dictionary object for JS:

http://jsfiddle.net/MickMalone1983/VEpFf/2/

If you didn't know, the AS3 dictionary allows you to use any object as the key, as opposed to just strings. They come in very handy once you've found a use for them.

It's not as fast as a native object would be, but I've not found any significant problems with it in that respect.

API:

//Constructor
var dict = new Dict(overwrite:Boolean);

//If overwrite, allows over-writing of duplicate keys,
//otherwise, will not add duplicate keys to dictionary.

dict.put(key, value);//Add a pair
dict.get(key);//Get value from key
dict.remove(key);//Remove pair by key
dict.clearAll(value);//Remove all pairs with this value
dict.iterate(function(key, value){//Send all pairs as arguments to this function:
    console.log(key+' is key for '+value);
});


dict.get(key);//Get value from key

2 Comments

Nice and useful library! I have added a get function, which I thought was missing and fixed some minor syntax issues (missing semicolon etc). Here's the modified fiddle: Dictionary in JSFiddle
Good job mate, dunno why that wasn't in there!
2

Firefox 13+ provides an experimental implementation of the map object similar to the dict object in python. Specifications here.

It's only avaible in firefox, but it looks better than using attributes of a new Object(). Citation from the documentation :

  • An Object has a prototype, so there are default keys in the map. However, this can be bypassed using map = Object.create(null).
  • The keys of an Object are Strings, where they can be any value for a Map.
  • You can get the size of a Map easily while you have to manually keep track of size for an Object.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.