Associative Arrays Must Die 17

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

  • Pingback: alexander kirk » Blog Archive » Misuse of the Array Object in JavaScript()

  • http://dean.edwards.name/ Dean Edwards

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

  • http://www.baconbutty.com Julian Turner

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

  • http://codinginparadise.org Brad Neuberg

    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

  • http://codinginparadise.org Brad Neuberg

    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

  • http://codinginparadise.org Brad Neuberg

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

    Best,
    Brad

  • http://erik.eae.net Erik Arvidsson

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

  • 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?

  • Irfan

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

  • http://codinginparadise.org Brad Neuberg

    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?

  • http://erik.eae.net Erik Arvidsson

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

  • http://erik.eae.net Erik Arvidsson

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

  • 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 == “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. :)

  • Pedro Andujar

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

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

  • Pedro Andujar

    Error.

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

  • Pedro Andujar
  • James

    But what actually makes them “harmful”? Nothing.