CppLearner
CppLearner

Reputation: 17040

How come I can't lookup associated array like this?

urlMap = {
    '0': {'6b4247404960fd4e418d242f3b7f0412': 'http://google.com', '123':'http://ibm.com'},
    '1': {'4c27ffaef99b7a6dbe838b46bcc09779' : 'http://yahoo.com', '456':'http://abc.com'}

};

    $(function() {
     var l = new Array(1,2,3,4);
     for (var i = 0; i < l.length; i++){
          $("#"+i.toString()+".foo").change(function() {
           g = i.toString();
               window.location.href = urlMap[g][$(this).val()];
    })}});

I tried to use urlMap[i] it won't work. When I hardcode urlMap['0'] it works.

From Firebug, I see this

urlMap[g] is undefined
[Break On This Error]   

window.location.href = urlMap[g][$(this).val()];

How am I suppose to lookup the dictionary?

Thanks.

Upvotes: 0

Views: 68

Answers (2)

T.J. Crowder
T.J. Crowder

Reputation: 1075199

It's very hard to tell what you're trying to do. You have a map that has two entries, with the keys "0" and "1", but you have a loop that's looping through the values 0, 1, 2, and 3, and then using those values to look up things in the map.

There are at least three problems with the quoted code:

  1. You're trying to access the keys "0", "1", "2", and "3" of an object that only has the keys "0" and "1".

  2. You're creating a function in a loop that's a closure over the variable i, and so will only see the value of i as of later, then the closure is called. This is because closures receive a live reference to the variable, not a copy of its value when they're created. So all of your click handler functions will try to use the key "4" (the value of i after the loop completes), which doesn't exist in your map.

  3. You're not declaring g anywhere, and so falling prey to The Horror of Implicit Globals.

Here's my best guess at what you're actually trying to do:

urlMap = {
    '0': {'6b4247404960fd4e418d242f3b7f0412': 'http://google.com', '123':'http://ibm.com'},
    '1': {'4c27ffaef99b7a6dbe838b46bcc09779' : 'http://yahoo.com', '456':'http://abc.com'}

};

$(function() {
    for (var i = 0; i < 2; i++){
        $("#"+i.toString()+".foo").change(createHandler(i));
    }

    function createHandler(index) {
       return function() {
           window.location.href = urlMap[index][$(this).val()];
       };
    }
});

Changes:

  1. I only try to access elements "0" and "1" of the map, since those are the only elements it has.

  2. I use the createHandler function to ensure that the handler we create is closing over the index argument to createHandler, rather than the i value in the loop. The index argument won't change, whereas i will (as I mentioned) change as the loop continues.

  3. I got rid of g, which we don't need, and just use index directly. Property names are always strings (even when the object is an "array"); any time you index into an object, if the index value you supply is a number, it'll get turned into a string, so you don't have to do it explicitly (though you might if you prefer).

Upvotes: 4

SLaks
SLaks

Reputation: 887867

As the error clearly states, urlMap[g] does not exist.
You need to create it first.

Upvotes: 1

Related Questions