Associative arrays in JavaScript

April 20, 2010

Today I had one of those it-came-to-me-as-I-was-under-the-shower moments. For some reason, a conversation from a couple of months ago popped back into my mind. Somebody had asked me about associative arrays in JavaScript. To which I simply replied something like, well, they’re just there, built into the language. Just use an object! You could technically even use an array (since JS arrays aren’t really arrays but hash tables with string keys whose strings happen to convert to integers), but that’s not a good idea for various reasons.

This morning I realized that my answer wasn’t entirely complete. Objects work fine as associative arrays a.k.a. hash tables a.k.a. dictionaries if your keys are strings or can be uniquely converted to strings (in which case you could write toString() methods for all your objects you want to use as keys.) Python is a bit less restrictive with its dictionaries and requires that your object be hashable. Immutable built-in types like strings and tuples are hashable, so as long as you can find a one-to-one unique mapping to those (and implement that in __hash__()), you’re good. The advantage of this system is that string representation and hashing aren’t mixed into one interface.

The good news is that thanks to the concept of object identity (present in both JavaScript and Python), you can actually write an associative array that accepts arbitrary keys:

function dict () {
    var keys = [];
    var values = [];

    return {
        get: function (key) {
            return values[keys.indexOf(key)]
        },

        set: function (key, value) {
            var i = keys.indexOf(key);
            if (i === -1) {
                i = keys.length;
            }
            keys[i] = key;
            values[i] = value;
        },

        del: function (key) {
            var i = keys.indexOf(key);
            keys.splice(i, 1);
            values.splice(i, 1);
        },

        keys: function () {
            return keys.slice();
        },

        values: function () {
            return values.slice();
        },
    };
}

I’m not going to bother with a Python implementation because it would look almost identical (modulo syntax). Also, if you find yourself wanting to use something like this in Python, you’re probably doing something wrong. Python’s dictionary implementation is insanely fast and the range of immutable types (strings, tuples, frozensets, etc.) should be sufficient.

And come to think of it, so far I haven’t felt the need for something like this in JavaScript either. But it came to me under the shower, so I had to write it down.

About these ads

2 Responses to “Associative arrays in JavaScript”

  1. ris Says:

    “so as long as you can find a one-to-one mapping to those (and implement that in __hash__()), you’re good”

    It does not have to be a one-to-one mapping. That’s the whole point of hashes.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: