2017-07-24 45 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) { 
相关问题