1

I was wondering if anyone could help figure out how i can set the value of a property in an object which can be found in a deep Array.

Below is an example of the Tree array

I would like to know how i can insert

var newObjectToInsert = {id: 999, name: 'new name'};

in the 'nodes' array of the object whose id === 3901

var tree = [
  {
    id: 1,
    name: 'Level 1 - A',
    nodes: [
      {
        id: 33,
        name: 'Level 2 = A',
        nodes: []
      },
      
      {
        id: 21,
        name: 'Level 2 = B',
        nodes: []
      }
    ]
  },
  
  {
    id: 2,
    name: 'Level 1 - B',
    nodes: []
  },
  
  {
    id: 3,
    name: 'Level 1 - B',
    nodes: [
      {
        id: 65,
        name: 'Level 2 = A',
        nodes: []
      },

      {
        id: 124,
        name: 'Level 2 = A',
        nodes: [
          {
            id: 3901,
            name: 'Level 3 - A'
          },
          
          {
            id: 29182,
            name: 'Level 3 - B',
            nodes: [
              {
                id: 32423413,
                name: 'Level 4 - A'
              }
            ]
          }
        ]
      },
  
      {
        id: 534,
        name: 'Level 2 = A',
        nodes: []
      }
    ]
  },
];

2 Answers 2

1

You can use a native Array#some to achieve a recursive traversal. An advantage towards using this approach is it already provides a mechanism to stop the traversal once it finds the node that we want to insert the new object.

var inserted = tree.some(function cb(v) {
  var nodes = v.nodes || [];
  return v.id === nodeId?
    (v.nodes = nodes).push(newObjectToInsert):
    nodes.some(cb);
});

var tree = [{
    id: 1,
    name: 'Level 1 - A',
    nodes: [{
        id: 33,
        name: 'Level 2 = A',
        nodes: []
      },

      {
        id: 21,
        name: 'Level 2 = B',
        nodes: []
      }
    ]
  },

  {
    id: 2,
    name: 'Level 1 - B',
    nodes: []
  },

  {
    id: 3,
    name: 'Level 1 - B',
    nodes: [{
        id: 65,
        name: 'Level 2 = A',
        nodes: []
      },

      {
        id: 124,
        name: 'Level 2 = A',
        nodes: [{
            id: 3901,
            name: 'Level 3 - A'
          },

          {
            id: 29182,
            name: 'Level 3 - B',
            nodes: [{
              id: 32423413,
              name: 'Level 4 - A'
            }]
          }
        ]
      },

      {
        id: 534,
        name: 'Level 2 = A',
        nodes: []
      }
    ]
  },
];

var newObjectToInsert = {id: 999, name: 'new name'};
var nodeId = 3901;

var inserted = tree.some(function cb(v) {
  var nodes = v.nodes || [];
  return v.id === nodeId?
    (v.nodes = nodes).push(newObjectToInsert):
    nodes.some(cb);
});

console.log(tree);
body > div { min-height: 100%; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

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

2 Comments

Thank you very much for sharing your knowledge. This works a treat and best of all, i have learnt something new! I knew i needed a recursive function but wasn't sure what the best way was. I have implemented this method and it works brilliantly @ryeballar
@MolikMiah, note that you can also use _.some as an alternative, if you're concerned about old browser versions that doesn't implement Array#some.
0

You have a recursive structure. So you visit all items you need a visitor.

Pseudo code:

function visit(visitor, tree) {
  visitor(tree);
  items.nodes.forEach(subTree => visit(visitor, subTree));
}

And use

visit(node => {
  if (node.id === 'whatever'){
    node.push({yournode});
  }
}, tree);

1 Comment

Thank you very much Basarat, this works a treat and it's very easy to understand :)

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.