views:

201

answers:

4

I want to create a hashtable of json objects, where each json object represents a user.

I want to do this to sort of create a client side 'cache' of users.

User { ID: 234, name: 'john', ..);

So I can then reference things like this:

if(userCache[userid] != null) alert(userCache[userid].ID);

is this possible?

+2  A: 

Javascript objects themselves are maps, so for instance:

var userCache = {};
userCache['john']     = {ID: 234, name: 'john', ... };
userCache['mary']     = {ID: 567, name: 'mary', ... };
userCache['douglas']  = {ID: 42,  name: 'douglas', ... };

// Usage:
var id = 'john';
var user = userCache[id];
if (user) alert(user.ID); // alerts "234"

(It wasn't clear to me whether your "userid" would be "john" or 234, so I went with "john" above, but you could use 234 if you preferred.)

It's up to the implementation how the keys are stored and whether the map is a hash map or some other structure, but I've done this with hundreds of objects and been perfectly happy with the performance, even on IE, which is one of the slower implementations (at the moment).

This works because there are two ways to get at the properties of a Javascript object: Via dotted notation, and via bracketed notation. For example:

var foo = {bar: 10};
alert(foo.bar);              // alerts "10"
alert(foo['bar']);           // alerts "10"
alert(foo['b' + 'a' + 'r']); // alerts "10"
s = "bar";
alert(foo[b]);               // alerts "10"

It may seem strange that this bracketed syntax for getting an object property by name is the same as getting an array element by index, but in fact, array indexes are object properties in Javascript. Property names are always strings (in theory), but auto-conversion occurs when you do things like user[234]. (And implementations are free to optimize-out the conversion if they can, provided the semantics are maintained.)

Edit Some bits and pieces:

Looping through the cache

And if you want to loop through the cache (and based on your follow-up question, you do, so perhaps others reading this question will want to too):

var key, user;
for (key in userCache) {
    // `key` receives the name of each property in the cache, so "john",
    // "mary", "douglas"...
    user = userCache[key];
    alert(user.ID);
}

The keys are looped in no defined order, it varies by browser.

Deleting from the cache

Suppose you want to delete a property from the cache entirely:

delete userCache['john'];

Now there is no longer a "john" property in the object at all.

T.J. Crowder
so when I am looping through the json requests, how do I add it to the hash?
Blankman
@Blankman: Literally as above, e.g., let's assume you've received a JSON string and deserialized it into an object for the user "john", which you're pointing at with the variable `data`. E.g., `data = JSON.parse(the_JSON_string_data);`. You add that to the `userCache` like this: `userCache[data.name] = data;` (if the `name` property is what you want to use as a key, or `userCache[data.ID] = data;` if the `ID` property is the key).
T.J. Crowder
A: 

This is almost verbatim your code, but it works, yes:

var cache = {}
cache[234] = { id: 234, name: 'john' }

if (cache[1]) alert('Hello ' + cache[1].name);
if (cache[234]) alert('Hello ' + cache[234].name);

Or was your question on how to implement this on the server side too, to get the user cache to the client?

Peter Jaric
Run my simple code on http://jsbin.com/atupi3Click the edit button in the top right corner to see the code.
Peter Jaric
A: 
function findUser(users, userid) {
    for (var i = 0; i < users.length; i++) {
        if (users[i].ID === userid) {
            return users[i];
        }
    }
    return null;
}

var users = [{ ID: 234, name: 'john' }, { ID: 235, name: 'smith' }];
var user = findUser(users, 235);
if (user != null) {
    alert(user.name);
}
Darin Dimitrov
A: 

Since all objects in Javascript are really dictionaries, you can do this in a couple ways. One way might be:

var dict = new Object;
dict.Bobby = { ID: 1, Name: "Bobby" };
if (dict.Bobby != null) alert(dict.Bobby.Name);
Bobby
using the dot-notation in the if statement is equivalent to the square-brackets, if you prefer that, just making the point.. also obviously my 'dict' object is your userCache
Bobby