2013-01-24 91 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

感謝您的幫助,我非常瞭解它 –