2017-07-24 44 views
0

我有一個樹結構的JSON應該被過濾,結果應該保留樹結構。如何有效地過濾保留其現有結構的樹視圖?

var tree = [ 
    { 
    text: "Parent 1", 
    nodes: [ 
     { 
     text: "Child 1", 
     type: "Child", 
     nodes: [ 
      { 
      text: "Grandchild 1" 
      type: "Grandchild" 
      }, 
      { 
      text: "Grandchild 2" 
      type: "Grandchild" 
      } 
     ] 
     }, 
     { 
     text: "Child 2", 
     type: "Child" 
     } 
    ] 
    }, 
    { 
    text: "Parent 2", 
    type: "Parent" 
    }, 
    { 
    text: "Parent 3", 
    type: "Parent" 
    } 
]; 

實施例:

1)如果搜索查詢是父1

預期結果:

[ 
    { 
    text: "Parent 1", 
    nodes: [ 
     { 
     text: "Child 1", 
     type: "Child", 
     nodes: [ 
      { 
      text: "Grandchild 1" 
      type: "Grandchild" 
      }, 
      { 
      text: "Grandchild 2" 
      type: "Grandchild" 
      } 
     ] 
     }, 
     { 
     text: "Child 2", 
     type: "Child" 
     } 
    ] 
    } 
] 

2)如果搜索查詢是兒童1

預期結果:

[ 
    { 
    text: "Parent 1", 
    nodes: [ 
     { 
     text: "Child 1", 
     type: "Child", 
     nodes: [ 
      { 
      text: "Grandchild 1" 
      type: "Grandchild" 
      }, 
      { 
      text: "Grandchild 2" 
      type: "Grandchild" 
      } 
     ] 
     } 
    ] 
    } 
] 

3)如果搜索查詢是孫子2

預期結果:

[ 
    { 
    text: "Parent 1", 
    nodes: [ 
     { 
     text: "Child 1", 
     type: "Child", 
     nodes: [ 
      { 
      text: "Grandchild 2" 
      type: "Grandchild" 
      } 
     ] 
     } 
    ] 
    } 
] 

我需要基於節點級別(這裏)保留樹結構。到目前爲止,我已經嘗試過濾遞歸,但無法重新映射結果。

angular.module("myApp",[]) 
    .filter("filterTree",function(){ 
     return function(items,id){ 
      var filtered = []; 
      var recursiveFilter = function(items,id){ 
       angular.forEach(items,function(item){ 
       if(item.text.toLowerCase().indexOf(id)!=-1){ 
        filtered.push(item); 
       } 
       if(angular.isArray(item.items) && item.items.length > 0){ 
        recursiveFilter(item.items,id);    
       } 
       }); 
      }; 
      recursiveFilter(items,id); 
      return filtered; 
     }; 
    }); 
}); 

我的JSON非常大,因此基於類型的重映射預計會在過濾器本身完成。 請指教。

回答

2

您可以使用嵌套遞歸方法並過濾樹,同時尊重找到的項目。

function filter(array, text) { 
 
    return array.filter(function iter(o) { 
 
     var temp; 
 
     if (o.text === text) { 
 
      return true; 
 
     } 
 
     if (!Array.isArray(o.nodes)) { 
 
      return false; 
 
     } 
 
     temp = o.nodes.filter(iter); 
 
     if (temp.length) { 
 
      o.nodes = temp; 
 
      return true; 
 
     } 
 
    }); 
 
} 
 

 
var tree = [{ text: "Parent 1", nodes: [{ text: "Child 1", type: "Child", nodes: [{ text: "Grandchild 1", type: "Grandchild" }, { text: "Grandchild 2", type: "Grandchild" }] }, { text: "Child 2", type: "Child" }] }, { text: "Parent 2", type: "Parent" }, { text: "Parent 3", type: "Parent" }]; 
 

 
console.log(filter(tree, 'Parent 1')); 
 
console.log(filter(tree, 'Child 1')); 
 
console.log(filter(tree, 'Grandchild 2'));
.as-console-wrapper { max-height: 100% !important; top: 0; }

將該溶液變異原始數組。如果您需要保留原始數組,則可以爲該數組的副本插入一個字符串化/解析部分。

return JSON.parse(JSON.stringify(array)).filter(function iter(o) { 
相關問題