Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

converting an array into a tree

can somebody explain this code? I don't get what is inside the "for" structure.

 var tree = {}

function addToTree(tree, array) { 
   for (var i = 0, length = array.length; i < length; i++) {
       tree = tree[array[i]] = tree[array[i]] || {}
   }
}

addToTree(tree, ["a", "b", "c"])
addToTree(tree, ["a", "b", "d"])

/*{
    "a": {
        "b": {
            "c": {},
            "d": {}
        }
    }
}*/
like image 508
Luis Palomá Avatar asked Jan 24 '13 17:01

Luis Palomá


2 Answers

I've expanded the body of the for loop and added some comments in attempt to make things more explicit.

for (var i = 0, length = array.length; i < length; i++) {
   // Assign the current item in the array to a variable
   var current = array[i];

   // If there is no property on the "tree" object corresponding to the value of 
   // "current", set this property to a new object
   if (!tree[current]) {
      tree[current] = {};
   }

   // Set the "tree" variable to the field in the "tree" object whose 
   // name corresponds to "current". On the next loop iteration, "tree" will
   // refer to this "child" object, resulting in a tree-like object being
   // created as we iterate.
   tree = tree[current];
}
like image 50
Donut Avatar answered Sep 30 '22 09:09

Donut


That's confusing before the reference to tree inside the function shadows the outer variable with the same name. But due to how references work in JavaScript, it ends up modifying the outer variable anyway.

Here is what it does, step by step, considering only the first call:

  1. Call function with a reference to tree (that is {}) and ["a", "b", "c"] as arguments
  2. Loop the array.
    1. Check if there is already a property "a" in the tree; if not, create it with value {}
    2. The full tree now looks like { a : {} }
    3. Now consider the tree we're working on is tree.a (which is empty)
    4. Check if there is already a property "b" in the current tree; if not, create it with value {}
    5. The full tree now looks like { a : { b: {} } }
    6. Now consider the tree we're working on is tree.a.b (which is empty)
    7. Check if there is already a property "c" in the current tree; if not, create it with value {}
    8. The full tree now looks like { a : { b: { c: {} } } }
    9. Now consider the tree we're working on is tree.a.b.c (which is empty)
  3. End of function
like image 23
bfavaretto Avatar answered Sep 30 '22 11:09

bfavaretto