2013-01-24 64 views
6

有人可以解释这段代码吗?我没有得到“for”结构中的内容。将数组转换为树

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": {} 
     } 
    } 
}*/ 
+1

呃...这个代码甚至可以工作吗?如果是这样,我想知道发生了什么。 –

+0

它将一个数组转换成一棵树,它就像一个对象树,注释代码是树的输出。这是原始帖子:http://stackoverflow.com/q/3663096/2007780 –

+2

这是一些丑陋的代码! – bfavaretto

回答

1

我已经扩大了for循环的正文,并添加了一些注释以试图使事情更加明确。

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]; 
} 
+0

哦,我现在明白了!起初,我认为我们在全局范围内写了树的值,但'tree'也是函数参数的名字! –

+2

@DanielAllenLangdon正确 - 这使得OP的帖子不必要的混淆,因为'addToTree'范围内'tree'的值将被绑定到传入的任何东西,在原始示例中它也恰好是全局变量' tree'。 – Donut

+0

伟大的我一直在寻找这一天。谢谢 –

1

这是令人困惑的,在函数内部引用tree之前,会遮蔽具有相同名称的外部变量。但由于JavaScript中的引用是如何工作的,它最终会修改外部变量。

这里是做什么的,一步一步的,只考虑第一个电话:

  1. 一起tree参考呼叫功能(即{})和["a", "b", "c"]作为参数
  2. 循环数组。
    1. 检查树中是否已经有属性“a”如果没有,用价值创造它{}
    2. 完整的树现在看起来像{ a : {} }
    3. 现在考虑我们正在处理的树是tree.a(里面是空的)
    4. 检查,如果已经有一个属性“B”在当前树中;如果没有,用价值创造它{}
    5. 完整的树现在看起来像{ a : { b: {} } }
    6. 现在考虑我们正在处理的树是tree.a.b(里面是空的)
    7. 检查,如果已经有一个属性“C”在当前树中;如果没有,用价值创造它{}
    8. 完整的树现在看起来像{ a : { b: { c: {} } } }
    9. 现在考虑我们正在处理的树是tree.a.b.c(里面是空的)的功能
  3. 结束
+0

感谢您的帮助,我非常了解它 –