2012-08-01 349 views
1

我試圖遍歷一個可以有幾個級別的數組的對象。通過嵌套對象/數組迭代

例如,

我開始:

var htmlString = { 
    "div": [{ 
     "attributes": { 
      "class": "myDivClass" 
     }, 
     "p": [{ 
      "attributes": { 
       "class": "myPClass" 
      } 
     }] 
    }] 
}; 

現在讓我們添加別的東西:

var htmlString = { 
    "div": [{ 
     "attributes": { 
      "class": "myDivClass" 
     }, 
     "p": [{ 
      "attributes": { 
       "class": "myPClass" 
      }, 
      "span": [{ 
       "attributes": { 
        "class": "mySpanClass" 
       } 
      }] 
     }] 
    }] 
}; 

我的工作將具有相同類型的形狀作爲代碼:

var childNode = document.createElement("myChildElement"); 
for (key in value) { 
    if (value.hasOwnProperty(key)) { 
     if (key == "attributes") { 
      childNode.setAttributes(myAttributes); // loop through attributes on the element 
     } 
     else { 
      //the same code ad infinitum 
      var childChildNode = document.createElement("myChildChildElement"); 
      // etc etc.... 
     } 
    } 
} 
parentNode.appendChild(childNode); 

每個額外元素的規則是相同的,所以我應該能夠以相同的方式循環這個數據結構爲b其他代碼,我只是不知道如何,但我會打賭有一個while()循環在那裏。誰能告訴我?

P.S.原生javascript,請不要jQuery! (雖然,如果你有YUI3的答案,我會非常感興趣)。

+4

您的示例中沒有JSON,只有JavaScript對象。對我來說,似乎你必須創建一個遞歸函數。 – 2012-08-01 17:07:03

+0

這不是我正在處理的實際代碼,但JSONLint對此感到滿意,因爲它是有效的JSON。是的,遞歸函數正是我所要求的,謝謝。 – Jezcentral 2012-08-01 17:19:57

+3

JSON是*數據交換格式*,它是JavaScript對象文字語法的一個子集,所以是的,某些對象文字也是有效的JSON,但這並不會使您的問題與JSON有任何關係。您正在問如何遞歸處理嵌套的JavaScript對象....與JSON沒有任何關係。我將更正您的問題... – 2012-08-01 17:21:54

回答

2
var createTree = function (node, data) { 
    for (var key in data) { 
     if (data.hasOwnProperty(key)) { 
      if (key == "attributes") { 
       node.setAttributes(myAttributes); // loop through attributes on the element 
      } 
      else { 
       for (var i = 0; i < data[key].length; ++i) { 
        var childNode = document.createElement(key); 
        createTree(childNode, data[key][i]); 
        node.appendChild(childNode); 
       } 
      } 
     } 
    } 
} 

createTree(parentNode, htmlString); 
+0

謝謝Qnan,當我有機會的時候我會測試它,但是看看這個,我可以看到你已經包含了一個永遠不會被引用的「數據」變量,並且當第一次調用這個變量時,parentNode和「div」將引用相同的節點,對嗎?不過,它向我展示瞭如何實現遞歸函數,所以非常感謝。 – Jezcentral 2012-08-02 09:52:00

+0

@ user1565354對不起,修正了這個問題。 「數據」實際上是指你所稱的「htmlString」的子樹,該函數必須處理。在第一次調用中,它將是htmlString本身。「div」是爲了成爲htmlString的最高關鍵字,「parentNode」是你想要附加的所有節點。 – Qnan 2012-08-02 13:17:06

+0

@ user1565354實際上它應該看起來有些不同 - 請參閱編輯 – Qnan 2012-08-02 13:30:02

0

好的,Qnan的代碼需要稍微調整一下,因爲它沒有處理正確地結束分支的末尾。一旦到了最後,就沒有什麼可以檢查的,沒有任何東西的空長度會導致錯誤。

我知道這是不好的做法,但已經晚了,我需要這個固定的,所以這裏是我的調整。

var createTree = function (node, data) { 
    for (key in data) { 
     if (data.hasOwnProperty(key)) { 
      if (key == "attributes") { 
       node.setAttributes(myAttributes); // loop through attributes on the element 
      } 
      else { 
       try { 
        for (var i = 0; i < data[key].length; ++i) { 
         var childNode = document.createElement(key); 
         createTree(childNode, data[key][i]); 
         node.appendChild(childNode); 
        } 
       } 
       catch(error) { 
        console.log("there was an error"); 
       } 
      } 
     } 
    } 
} 

createTree(parentNode, htmlString); 

是的,沒錯,我通過嘗試/捕捉它來掩蓋錯誤......然後什麼都不做。不要在家裏試試這個孩子!

Qnan,非常感謝。

+0

這很有趣。你準確地輸入了什麼?小提琴在這裏http://jsfiddle.net/S6ZGK/4/就像在你的例子中一樣走樹,但顯示彈出窗口而不是設置元素屬性,並且似乎不會導致任何錯誤。 – Qnan 2012-08-03 23:40:54

+0

它會更喜歡的:var htmlString = { 「DIV」:[{ 「屬性」:{ 「類」: 「myDivClass」 }, 「P」:[{ 「屬性」:{ 「類「: 」myPClass「 }, 」跨度「:[{ 」屬性「:{ 」類「: 」mySpan「 } }] }], 」DIV「:[{ 」屬性「 :{ 「class」:「myDiv」 }, 「span」:[{「{」「attributes」:{ 「class」:「class2」 } }] }] }]] }; – Jezcentral 2012-08-04 21:52:19

+0

爲了清楚起見,我確信任何由於執行代碼而產生的錯誤都是由於我而不是你。 :) – Jezcentral 2012-08-04 21:56:18