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 ;-)

17 Responses to “Associative Arrays Must Die”

  1. alexander kirk » Blog Archive » Misuse of the Array Object in JavaScript Says:

    [...] via Erik Arvidsson. [...]

  2. Dean Edwards Says:

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

  3. Julian Turner Says:

    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 “[ ]“.

  4. Brad Neuberg Says:

    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 –> jim@gmail.com
    Brad Neuberg –> bkn3@columbia.edu
    Billy Bob –> toothless@hillbilly.com

    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: “jim@gmail.com”};
    contacts["_Jim Jones"] = {name: “Jim Jones”, email: “jim@gmail.com”};

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

    // etc.

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

  5. Brad Neuberg Says:

    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 –> jim@gmail.com
    Brad Neuberg –> bkn3@columbia.edu
    Billy Bob –> toothless@hillbilly.com

    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: “jim@gmail.com”};
    contacts["_Jim Jones"] = {name: “Jim Jones”, email: “jim@gmail.com”};

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

    // 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

  6. Brad Neuberg Says:

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

    Best,
    Brad

  7. Erik Arvidsson Says:

    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.)

  8. Irfan Says:

    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?

  9. Irfan Says:

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

  10. Brad Neuberg Says:

    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?

  11. Erik Arvidsson Says:

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

  12. Erik Arvidsson Says:

    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;
    });

  13. Pedro Andujar Says:

    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 == “bkn3@columbia.edu”) array[index].email = “brad@columbia.edu” ;

    }

    var contacts = new Array();
    contacts["_Jim Jones"] = {name: “Jim Jones”, email: “jim@gmail.com”};
    contacts["_Brad Neuberg"] = {name: “Brad Neuberg”, email: “bkn3@columbia.edu”};

    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. :)

  14. Pedro Andujar Says:

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

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

  15. Pedro Andujar Says:

    Error.

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

  16. Pedro Andujar Says:

    You will be able to see complete code here, http://www.andrewdupont.net/2006/05/18/javascript-associative-arrays-considered-harmful/

    Good bye.

  17. James Says:

    But what actually makes them “harmful”? Nothing.

Leave a Reply