3

I currently have this object:

var obj = {
    1: {
    title: 'test',
    children: {
        2: {
        title: 'test2',
        children: {}
      },
      3: {
        title: 'test3',
        children: {}
      }
    }
  }
};

The whole idea is I make a function to add an item to this object. As parameter I send the parent.

Now, I was wondering how I would get the right item object. For example if I send parent '2', it would get 2: from the children of 1:. The only way I can think of is a for loop, but I don't know if there's a more efficient way. The children can be extended even more, so a parent has children, those children have children endlessly. That's the whole idea at least.

I think with a few items a for loop is okay, but I think if I have over 50 items it's already slow, and it'll even be slower with more.

thefourtheye
  • 233,700
  • 52
  • 457
  • 497
Joshua Bakker
  • 2,288
  • 3
  • 30
  • 63
  • *"if I have over 50 items it's already slow"* – well, depends on your definition of "slow", but a 50-time recursion would take at most fractions of milliseconds. In any case... – JJJ Jan 05 '16 at 09:55
  • Possible duplicate of [Find property by name in a deep object](http://stackoverflow.com/questions/15642494/find-property-by-name-in-a-deep-object) – JJJ Jan 05 '16 at 09:55

2 Answers2

3

This solution use Object.keys() for getting all keys of the given object and an array iteration with short ciruit Array.prototype.some() looks for the key. If found the reference is returned, otherwise the item is checked for an object. If so the object reference is taken for a new search with getReference().

var obj = { 1: { title: 'test', children: { 2: { title: 'test2', children: {} }, 3: { title: 'test3', children: {} } } } };

function getReference(o, p) {
    var r;
    Object.keys(o).some(function (k) {
        if (k === p) {
            r = o[k];
            return true;
        }
        if (typeof o[k] === 'object') {
            r = getReference(o[k], p);
            return !!r;
        }
    });
    return r;
}

var x = getReference(obj, '2');
document.write(x.title);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

If you want adding to be fast, you can preserve indexes of your child nodes in object or map (ES6). It could look like this:

function Tree() {
    this.data = {};
    this.indexes = {0: this.data};
}

Tree.prototype = {
    addNode: function(parentIndex, index, node) {
        // handle cases when parentIndex does not exist
        // handle cases when index already exists
        this.indexes[index] = node;
        var parent = this.indexes[parentIndex];
        parent.children = parent.children || {};
        parent.children[index] = node;            
    }
}

var tree = new Tree();

tree.addNode(0, 1, { title: 'test' });
tree.addNode(1, 2, { title: 'test2' });
tree.addNode(1, 3, { title: 'test3' });

console.log(tree.data);
madox2
  • 49,493
  • 17
  • 99
  • 99