Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript: multi-dimensional object

I want to create an object, starting from something like:

var map = {};

Then, I want to add items with this function:

add = function(integerA, objectB) {
    map[objectB.type][integerA] = objectB;
}

So, this is a random example of the object structure I want to achieve:

map = {
    'SomeType' : { 0 : 'obj', 2 : 'obj', 3 : 'obj' },
    'OtherType' : { 0 : 'obj', 5 : 'obj' },
};

Now, my problem. I can't do map[objectB.type][integerA] = objectB; because map[objectB.type] is not defined. I could solve this by checking if map[objectB.type] exists through an if-statement and create map[objectB.type] = {}; when necessary.

Otherwise I could pre-load all object types. However I would prefer not to have to do this.

My question: is there a way I can create the object 'on the fly' without having to check if the type already exists every time I want to call the add function or to pre-load all the types?

It is important that my add function is so fast as possible and that the map object is correct, because I need to read and write a lot in a small amount of time (it's an animation / game application).

like image 817
user8363 Avatar asked Jul 10 '11 20:07

user8363


3 Answers

No, there is no any other way to create objects on the fly. Only check for existence every time:

add = function(integerA, objectB) {
    if (!map[objectB.type]) {
        map[objectB.type] = {};        
    }
    map[objectB.type][integerA] = objectB;
}

If you want to improve performance you might consider some caching technics.

like image 68
bjornd Avatar answered Sep 28 '22 08:09

bjornd


You can use the boolean OR shortcut (which avoids at least an explicit if). It might not be that readable though:

var data = map[objectB.type] || (map[objectB.type] = {});
data[integerA] = objectB;

This works because an assignment actually returns the value that was assigned and an OR expression returns the first value that evaluates to true.

I don't think using an if has any impact on the performance though (actually, the way in my answer might be even "slower").

like image 32
Felix Kling Avatar answered Sep 28 '22 07:09

Felix Kling


If you use the map only for lookups and you don't need to iterate over the dimensions, you could merge your dimensions into a single key. For example:

add = function(integerA, objectB) {
    var key = objectB.type + '-' + integerA;
    map[key] = objectB;
}
like image 45
casablanca Avatar answered Sep 28 '22 07:09

casablanca