0

I have two objects that look like this:

var cache = {
 '39' : { id : 39, name : 'Tom' },
 '40' : { id : 40, name : 'David'},
 '41' : { id : 41, name : 'Daniel'},
 '356': { id :356, grp: 'ROM', fee: '$35'} 
}

var tree = {
 person : { id : 39 },
 memberships : { id : 356 },
}

What I'm trying to do is to write a recursive function that will take the tree object as an argument and generate a data structure that references/links to the corresponding object in the cache object. So finally I must be able to access user 'Tom' like this: tree.person.name.

I'm using recursion for two reasons:

  1. My actual tree object is way more complicated than what I have shown here (it is nested)
  2. It varies depending on the user input and the depth of the tree is unknown

I wrote this recursive function to do the referencing/linking:

var traverse = function (jsonObj) {
    if( typeof jsonObj == "object" ) { 
        if(cache[jsonObj.id]){
          jsonObj = Ocache[jsonObj.id];

      }
      $.each(jsonObj, function(k, v) {
        traverse(v);
      });
    }
    else {
        // jsonObj is a number or string
    }
  }

Then I call the function like

   traverse(tree);

but when I use the debugger to see my tree object, nothing has changed: tree is the same as before. How do I achieve this and reference/link objects in the cache object?

1
  • Can you post desired result, also $.each() is jquery. Commented Jul 4, 2016 at 22:16

1 Answer 1

1

The main problem in your code is jsonObj = cache[jsonObj.id]: Here you're overwriting jsonObj, a local variable in traverse, which has no effect on anything outside of this particular function call.

In order to make changes to the nested tree object itself, you have to keep track of the parent object and the current key:

var cache = {
    '39' : { id: 39, name: 'Tom' },
    '40' : { id: 40, name: 'David'},
    '41' : { id: 41, name: 'Daniel'},
    '356': { id: 356, grp: 'ROM', fee: '$35'} 
};

var tree = {
    person: { id: 39 },
    memberships: { id: 356 },
};

function traverse(obj) {
    for (var k in obj) {
        var v = obj[k];
        if (!v || typeof v !== 'object') continue;
        if (cache[v.id]) {
            obj[k] = cache[v.id];
        } else {
            traverse(v);
        }
    }
}

traverse(tree);

console.log(tree);

I added the !v check because typeof null is object, but we don't want to recurse into null.

I did not fix that an object without an id is treated as having id: 'undefined' (if you don't want that, add an additional check to the if (cache[v.id]) line).

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much for the reply. This works perfectly for the given tree object. But I just realized that there are arrays of objects in the 'tree' object. Like the following var tree = { person: { id: 39 }, memberships: [ { id: 356 }, { id : 370} ], contacts: { phonenumbers : [{ id : 150}, {id : 171}] } }; how do I extend the above solution for these kind of objects?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.