4

I need a way to add an object into another object. Normally this is quite simple with just

obj[property] = {'name': bob, 'height': tall}

however the object in question is nested so the following would be required:

obj[prop1][prop2] = {'name': bob, 'height': tall}

The clincher though, is that the nesting is variable. That is that I don't know how deeply each new object will be nested before runtime. Basically I will be generating a string that represents an object path like

"object.secondObj.thirdObj.fourthObj"

and then I need to set data inside the fourth object, but I can't use the bracket [] method because I don't know how many brackets are required beforehand. Is there a way to do this? I am using jQuery as well, if that's necessary.

Lee Taylor
  • 7,761
  • 16
  • 33
  • 49
Tevis
  • 729
  • 1
  • 12
  • 27
  • 1
    I guess you can make use of [Building object hierarchy from a 'namespace' string](http://stackoverflow.com/questions/2308783/building-object-hierarchy-from-a-namespace-string) or [Javascript nested objects from string](http://stackoverflow.com/questions/7640727/javascript-nested-objects-from-string) -- should not be difficult to adjust. – Felix Kling Aug 30 '12 at 22:12
  • How will the data be coming in that's creating these objects & their Data? – Mark Pieszak - Trilon.io Aug 30 '12 at 22:12

2 Answers2

4

Sure, you can either use recursion, or simple iteration. I like recursion better. The following examples are meant to be proof-of-concept, and probably shouldn't be used in production.

var setDeepValue = function(obj, path, value) {
    if (path.indexOf('.') === -1) {
        obj[path] = value;
        return;
    }

    var dotIndex = path.indexOf('.');
    obj = obj[path.substr(0, dotIndex)];

    return setDeepValue(obj, path.substr(dotIndex + 1), value);
};

But recursion isn't necessary, because in JavaScript you can just change references.

var objPath = 'secondObj.thirdobj.fourthObj';
var valueToAdd = 'woot';

var topLevelObj = {};
var attributes = objPath.split('.');
var curObj = topLevelObj;

for (var i = 0; i < attributes.length; i++) {
    var attr = attributes[i];
    if (typeof curObj[attr] === 'undefined') {
        curObj[attr] = {};
    }

    curObj = curObj[attr];

    if (i === (attributes.length - 1)) {
        // We're at the end - set the value!
        curObj['awesomeAttribute'] = valueToAdd;
    }
}
voithos
  • 68,482
  • 12
  • 101
  • 116
  • Thank you! This worked flawlessly. I've been banging my head against this for a while now :) – Tevis Aug 30 '12 at 22:40
0

Instead of generating a string...

var o="object";
//code
o+=".secondObj";
//code
o+=".thirdObj";
//code
o+=".fourthObj";

...you could do

var o=object;
//code
o=o.secondObj;
//code
o=o.thirdObj;
//code
o=o.fourthObj;

Then you can add data like this:

o.myprop='myvalue';

And object will be updated with the changes.

See it here: http://jsfiddle.net/rFuyG/

Oriol
  • 274,082
  • 63
  • 437
  • 513