2013-07-10 83 views
1

我有沒有確定的程度JSON樹,它看起來像這樣:刪除對象元素在JavaScript

var nodeset = { 
    "name" : "FORM", 
    "attributes" : { 
     "IDFORM" : "59", 
     "NOMDOC" : "1", 
     "VERSFORM" : "1.01", 
     "DATEREPORT" : "10.10.1988" 
    }, 
    "nodes" : [{ 
      "name" : "PART1", 
      "persist" : true, 
      "nodes" : [{ 
        "name" : "FTYPE", 
        "persist" : true, 
        "value" : "1", 
        "weight" : 1 
       }, { 
        "name" : "STARTDATE", 
        "persist" : true, 
        "value" : "01.10.2011", 
        "weight" : 1 
       }, { 
        "name" : "ENDDATE", 
        "persist" : true, 
        "value" : "31.12.2011", 
        "weight" : 1 
       } 
      ], 
      "value" : "31.12.2011", 
      "weight" : 3 
     }, { 
      "name" : "PART2", 
      "persist" : true, 
      "nodes" : [{ 
        "name" : "F203", 
        "persist" : true, 
        "value" : 12, 
        "weight" : 1 
       }, { 
        "name" : "F204", 
        "persist" : true, 
        "value" : 12, 
        "weight" : 1 
       }, { 
        "name" : "STI059DETAIL", 
        "persist" : false, 
        "nodes" : [{ 
          "name" : "F1", 
          "persist" : false, 
          "value" : "asd", 
          "weight" : 1 
         }, { 
          "name" : "F2", 
          "persist" : false, 
          "value" : "asd", 
          "weight" : 1 
         }, { 
          "name" : "F3", 
          "persist" : false, 
          "value" : 0, 
          "weight" : 0 
         }, { 
          "name" : "F4", 
          "persist" : false, 
          "value" : 0, 
          "weight" : 0 
         } 
        ], 
        "value" : 0, 
        "weight" : 2 
       }, { 
        "name" : "STI059DETAIL", 
        "persist" : false, 
        "nodes" : [{ 
          "name" : "F1", 
          "persist" : false, 
          "value" : null, 
          "weight" : 0 
         }, { 
          "name" : "F2", 
          "persist" : false, 
          "value" : null, 
          "weight" : 0 
         }, { 
          "name" : "F3", 
          "persist" : false, 
          "value" : 0, 
          "weight" : 0 
         }, { 
          "name" : "F4", 
          "persist" : false, 
          "value" : 0, 
          "weight" : 0 
         } 
        ], 
        "value" : 0, 
        "weight" : 0 
       }, { 
        "name" : "STI059DETAIL", 
        "persist" : false, 
        "nodes" : [{ 
          "name" : "F1", 
          "persist" : false, 
          "value" : null, 
          "weight" : 0 
         }, { 
          "name" : "F2", 
          "persist" : false, 
          "value" : null, 
          "weight" : 0 
         }, { 
          "name" : "F3", 
          "persist" : false, 
          "value" : 0, 
          "weight" : 0 
         }, { 
          "name" : "F4", 
          "persist" : false, 
          "value" : 0, 
          "weight" : 0 
         } 
        ], 
        "value" : 0, 
        "weight" : 0 
       } 
      ], 
      "value" : 0, 
      "weight" : 4 
     } 
    ], 
    "weight" : 7 
}; 

我的任務是從中刪除所有節點,其中weight0nodes屬性存在。

由於它是一棵樹,我試着使用遞歸函數如下:

function clean(index, owner){ 
    var node = owner[index], 
     weight = node.weight; 

    delete node.weight; 

    if(typeof node.persist != 'undefined'){ 
     delete node.persist; 
    } 

    if(!node.nodes)return; 

    if(!weight){ 
     owner.splice(index, 1); 
    } 

    for(var i = 0; i < node.nodes.length; i++){ 
     clean(i, node.nodes); 
    } 
} 

for(var i = 0; i < nodeset.nodes.length; i++){ 
    clean(i, nodeset.nodes); 
} 

但不知何故splice(),不從那裏刪除任何東西。我用delete owner[index]取代了它,這會導致null值在這些節點的位置(我不想在那裏看到:()。

我的問題:爲什麼splice()函數不能像我期望的那樣工作(不會刪除節點)?另外,我採取了正確的做法嗎?如果不是,那麼任何其他建議,將不勝感激。

問候。

測試小提琴HERE,如果它可能有所幫助。

+0

當一個節點權重爲0,在那個節點爲根的整個子樹需要去? –

+0

是的。它需要。只允許'weight' ='0'的'value'節點。整個子樹不是。 – BlitZ

回答

3

您可以使用Array.filterArray.forEach過濾出0權重的節點。首先,定義一個謂詞:

var keepNode = function(node) { 
    return !(node.weight == 0 && node.hasOwnProperty("nodes")); 
}; 

然後函數來清潔不希望孩子的節點,然後遞歸上的剩餘子女:

function clean(tree) { 
    if (tree.nodes) { 
     tree.nodes = tree.nodes.filter(keepNode); 
     tree.nodes.forEach(clean); 
    } 
} 

最後,過程中的整個數據結構:

clean(nodeset); 

幾乎可以肯定有一種更優雅的方式可以在篩選時進行遞歸,但這應該可以完成這項工作。

EDIT(因爲我沒有注意到IE8標籤)

對於IE8(不支持filter),你有兩個選擇。您可以使用將大多數EcmaScript函數添加到傳統JS引擎的ES5 shim package。另外,您也可以使用此墊片(可進一步下來filter的文檔頁面上面鏈接上):

if (!Array.prototype.filter) 
{ 
    Array.prototype.filter = function(fun /*, thisp*/) 
    { 
    "use strict"; 

    if (this == null) 
     throw new TypeError(); 

    var t = Object(this); 
    var len = t.length >>> 0; 
    if (typeof fun != "function") 
     throw new TypeError(); 

    var res = []; 
    var thisp = arguments[1]; 
    for (var i = 0; i < len; i++) 
    { 
     if (i in t) 
     { 
     var val = t[i]; // in case fun mutates this 
     if (fun.call(thisp, val, i, t)) 
      res.push(val); 
     } 
    } 

    return res; 
    }; 
} 
+0

感謝您的努力。 IE8不喜歡'Array.filter'。 – BlitZ

+0

它仍然適用於最新的Chrome瀏覽器。但在IE中不能解決問題。 – BlitZ

+0

@CORRUPT - 哎呀。沒有注意到IE8標籤。我編輯了這篇文章。 –