2

Assume that I need a JavaScript dictionary (object/ associative array) which I need to access as follows:

var value = dict[foo][bar][buz][qux]; // this could go on

Which is the best way to initialize this dictionary? The only way I can think of is:

// 'foo', 'bar', 'baz', 'qux' are variables
var dict = {};
dict[foo] = {};
dict[foo][bar] = {};
dict[foo][bar][buz] = {};
dict[foo][bar][buz][qux] = value;

Alternatively, is there a better way of achieving the same results? I would prefer a solution that works both in browsers and Node.js.

adrianp
  • 2,491
  • 5
  • 26
  • 44

3 Answers3

2

Use JSON.parse:

var dict = JSON.parse('{ "' + foo + '": { "' + bar + '": { "' + buz + '": { "' + qux + '": "value"}}}}');
ramayac
  • 5,173
  • 10
  • 50
  • 58
ghost
  • 769
  • 5
  • 11
2

An option is to build the object dynamically, like:

var vals = [1, 2, 3, 4];

function createObject(arr) {
    var obj = {};
    var mod = obj;
    for (var i = 0, j = arr.length; i < j; i++) {
        if (i === (j - 1)) {
            mod.value = arr[i];
        } else {
            mod[arr[i]] = {};
            mod = mod[arr[i]];
        }
    }
    return obj;
}

console.log(createObject(vals));

DEMO: http://jsfiddle.net/BnkPz/

So your list of variables would have to be put into an array and passed to the function, or the function could modified to work with any number of passed arguments.

Ian
  • 50,146
  • 13
  • 101
  • 111
  • This seems to be the nicest solution, I'll probably accept it. – adrianp Apr 30 '13 at 06:34
  • @adrianp Accept whatever works best for you. Your original question was a little confusing, so as long as a solution works for you and works well, go with that. Ask anyone questions if you want to understand more about a solution – Ian Apr 30 '13 at 13:33
0

You could create a function that takes the object to modify, a path to the leaf property (a dot-delimited string like foo + '.' + bar + '.' + buz + '.' + qux), and the value, and let it loop and do the job for you:

var foo = 'foo',
    bar = 'bar',
    buz = 'buz',
    qux = 'qux',
    path = foo + '.' + bar + '.' + buz + '.' + qux,
    dict = {};

createNestedProperty(dict, path, 10);
console.log(dict);

function createNestedProperty(dict, path, value) {
    var pathArray = path.split('.'),
        current;
    while(pathArray.length) {
        current = pathArray.shift();
        if(!dict.hasOwnProperty(current)) {
            if(pathArray.length) {
                dict[current] = {};  
            // last item
            } else {
                dict[current] = value;     
            }
        }
    }
}

http://jsfiddle.net/NuqtM/

Also, a similar question was asked here: Extend a JavaScript object by passing a string with the path and a value.

Community
  • 1
  • 1
bfavaretto
  • 71,580
  • 16
  • 111
  • 150
  • While this solution does its job, I'm a little concerned about its "maintainability" (for anyone inheriting my project). – adrianp Apr 30 '13 at 06:38