Associative Arrays Must Die

Andrew Dupont wrote an excellent post explaining why using Array for maps/hashes/asssociative arrays are considered harmful. If you use Arrays for hashes in JavaScript you should be ashamed of yourself ;-)

16 comments

  1. Hooray! Now I can extend the Array object and not feel guilty. :-)

  2. I noted that there was some suggestion that the author did not rule out “custom properties” to “augment” the Array object.

    This may still be a concern, if these “custom properties” were more than simply extensions to the Array prototype. For instance, if you created on a given instance of Array some properties to record some additional “state” information relating to that particular instance, then this could be a slippery slope, and would it not provide some difficulties if you wished to serialise into a JSON string – i.e. you would need to use the Object literal “{ }” to serialise that additional “state” information, rather than simply an Array literal “[ ]“.

  3. I use Arrays as hashtables in a special situation: if I want my data to be linear for quick iterating over, while also wanting random access by key with O(1) lookup. For example, imagine I have a list of contacts in my address book, keyed against their email address:

    key –> value
    — —–
    Jim Jones –> [email protected]
    Brad Neuberg –> [email protected]
    Billy Bob –> [email protected]

    Lets say sometimes I want to enumerate over everything, which a hashtable can’t give me; and sometimes I want quick random access, which an array can’t give me. This is especially important for large data sets, since I can also sort using the sort function on arrays.

    An example of all of this:

    var contacts = new Array();

    // add data

    // Jim Jones
    contacts[contacts.length] = {name: “Jim Jones”, email: “[email protected]”};
    contacts["_Jim Jones"] = {name: “Jim Jones”, email: “[email protected]”};

    // Brad Neuberg
    contacts[contacts.length] = {name: “Brad Neuberg”, email: “[email protected]”};
    contacts["_Brad Neuberg"] = {name: “Brad Neuberg”, email: “[email protected]”};

    // etc.

    // enumerating over entries
    for(var i = 0; i

  4. I use Arrays as hashtables in a special situation: if I want my data to be linear for quick iterating over, while also wanting random access by key with O(1) lookup. For example, imagine I have a list of contacts in my address book, keyed against their email address:

    key –> value
    — —–
    Jim Jones –> [email protected]
    Brad Neuberg –> [email protected]
    Billy Bob –> [email protected]

    Lets say sometimes I want to enumerate over everything, which a hashtable can’t give me; and sometimes I want quick random access, which an array can’t give me. This is especially important for large data sets, since I can also sort using the sort function on arrays.

    An example of all of this:

    var contacts = new Array();

    // add data

    // Jim Jones
    contacts[contacts.length] = {name: “Jim Jones”, email: “[email protected]”};
    contacts["_Jim Jones"] = {name: “Jim Jones”, email: “[email protected]”};

    // Brad Neuberg
    contacts[contacts.length] = {name: “Brad Neuberg”, email: “[email protected]”};
    contacts["_Brad Neuberg"] = {name: “Brad Neuberg”, email: “[email protected]”};

    // etc.

    // enumerating over entries
    for(var i = 0; i < contacts.length; i++){
    var entry = contacts[i];
    alert(entry.name + “: ” + entry.email);
    }

    // random access
    var bradNeuberg = contacts["_Brad Neuberg"];

    // sorting
    contacts.sort(); // you will want to pass your own comparator in, or
    // provide a toString() method on object literal

    Note the _ when keying; this is to handle an important edge condition, where the key might be a number; if I don’t add a _ before a numbered key, such as 24, then this will be interpreted as an array index and will overwrite the entry that was there before:

    contacts["24"] = // bad!
    contacts["_24"] = // good!

    So associative arrays using Array aren’t necessarily bad; they’ve saved my butt in some situations :)

    Best,
    Brad Neuberg

  5. You need to escape < and > in comments, since they are going into the HTML and munging things.

    Best,
    Brad

  6. I don’t think your example was very good. You could have used a for-in-loop over an Object here.

    If you want a random contact there is a good idea to use an array because you could just generate a random number but in that case you could have used an Array and an Object.

    (Yeah, I know the Word Press comment field sucks but I don’t know if I’ll do anything about that.)

  7. Irfan

    Its a good .. here is a question
    contacts.sort(); this will sort the array by NAME
    How can be done if need is to sort by email?

  8. Irfan

    contacts.sort(); bydefault sort the array by Name
    how Can I sort the array by email

  9. But doesn’t a for-in-loop over an object not necessarily guarantee that you will get the same ordering that you put in, unlike an Array?

  10. The ECMAScript standards says that the order is not guaranteed but all implementations do guarantee the order.

  11. Irfan: Using Brad’s contacts array:

    contact.sort(function(c1, c2) {
    if (c1.email < c2.email) {
    return -1;
    }
    if (c1.email > c2.email) {
    return 1;
    }
    return 0;
    });

  12. Pedro Andujar

    Hello.
    I’m Spanish
    I speak little English
    My code based on forEach.

    Array.prototype.for_each= function(f,obj){

    var lg = this.length;
    var temp = this;
    if(lg “);
    if(element.email == “[email protected]”) array[index].email = “[email protected]” ;

    }

    var contacts = new Array();
    contacts["_Jim Jones"] = {name: “Jim Jones”, email: “[email protected]”};
    contacts["_Brad Neuberg"] = {name: “Brad Neuberg”, email: “[email protected]”};

    contacts.for_each(write_contacts);
    contacts.for_each(write_contacts);

    function write_number(element,index, array){
    document.write(“[" + index + "] = ” + element + “”);
    }

    var number = ["zero","one","two"];
    number.for_each(write_number);

    Good bye. :)

  13. Pedro Andujar

    Array.prototype.for_each = function(f,obj){

    var lg = this.length;
    var temp = this;
    if(lg

  14. Pedro Andujar

    Error.

    I’m sorry. I can’t send complete code.

  15. Pedro Andujar
  16. James

    But what actually makes them “harmful”? Nothing.

Comments are closed.