代码之家  ›  专栏  ›  技术社区  ›  margherita pizza

具有递归关系的javascript过滤器

  •  2
  • margherita pizza  · 技术社区  · 6 年前

    我的用例是这样的。

    • 我有一个称为位置的对象数组。
    • 它包含有关省、区和市的信息。
    • 市属于区,区属于省。
    • 如果 parent_region_id null 意味着它是一个省。
    • 如果 父区域ID 是一个省的ID表示它是一个地区。
    • 否则它就是一个城市。

    我的目标是从阵列中筛选出所有城市。 我做了一个奇怪的方式,但它工作。

    但我想知道什么是最理想的方法来做到这一点? 这是我的工作代码。

    const locations = [
    {id:1,name:"Western province",parent_region_id:null},
    {id:2,name:"Southern province",parent_region_id:null},
    {id:3,name:"Central province",parent_region_id:null},
    {id:4,name:"Colombo district",parent_region_id:1},
    {id:5,name:"Galle district",parent_region_id:2},
    {id:6,name:"Kandy district",parent_region_id:3},
    {id:7,name:"Maharagama",parent_region_id:4},
    {id:8,name:"Nugegoda",parent_region_id:4},
    {id:9,name:"Peradeniya",parent_region_id:6},
    ]
    
    //get the province ids first
    
    const provinces = []
    
    locations.forEach(e=> {
    if(!e.parent_region_id){
      provinces.push(e.id)
    }
    })
    
    // get all the districts then
    
    const districts = []
    
    locations.forEach(e=>{
      if(provinces.includes(e.parent_region_id)){
      districts.push(e.id) 
      }
    })
    
    
    //get cities
    
    const cities = [];
    
    
    locations.forEach(e=> 
    {
      if(!districts.includes(e.id) && !provinces.includes(e.id)){
        console.log(e.name," is a city")
      }
    })
    2 回复  |  直到 6 年前
        1
  •  2
  •   kockburn    6 年前

    使用 Array#filter Array#find .

    const locations=[{id:1,name:"Western province",parent_region_id:null},{id:2,name:"Southern province",parent_region_id:null},{id:3,name:"Central province",parent_region_id:null},{id:4,name:"Colombo district",parent_region_id:1},{id:5,name:"Galle district",parent_region_id:2},{id:6,name:"Kandy district",parent_region_id:3},{id:7,name:"Maharagama",parent_region_id:4},{id:8,name:"Nugegoda",parent_region_id:4},{id:9,name:"Peradeniya",parent_region_id:6},]
    
    const res = locations.filter(({id, parent_region_id},i,a)=>{
      if(!parent_region_id) return false;
      const loc = a.find(l=>l.id === parent_region_id);
      return !loc.parent_region_id ? false : true;
    });
    
    console.log(res);

    解决方法是先删除省份:

    const locations=[{id:1,name:"Western province",parent_region_id:null},{id:2,name:"Southern province",parent_region_id:null},{id:3,name:"Central province",parent_region_id:null},{id:4,name:"Colombo district",parent_region_id:1},{id:5,name:"Galle district",parent_region_id:2},{id:6,name:"Kandy district",parent_region_id:3},{id:7,name:"Maharagama",parent_region_id:4},{id:8,name:"Nugegoda",parent_region_id:4},{id:9,name:"Peradeniya",parent_region_id:6},]
    
    const res = locations
    .filter(({parent_region_id})=>parent_region_id!==null)
    .filter(({parent_region_id},i,a)=>{
      return a.findIndex(l=>l.id === parent_region_id) > -1;
    });
    
    console.log(res);
        2
  •  0
  •   Jack Bashford    6 年前

    如果要使代码更清晰、更紧凑,请尝试使用 filter() 像这样:

     
    
    const locations = [
    {id:1,name:"Western province",parent_region_id:null},
    {id:2,name:"Southern province",parent_region_id:null},
    {id:3,name:"Central province",parent_region_id:null},
    {id:4,name:"Colombo district",parent_region_id:1},
    {id:5,name:"Galle district",parent_region_id:2},
    {id:6,name:"Kandy district",parent_region_id:3},
    {id:7,name:"Maharagama",parent_region_id:4},
    {id:8,name:"Nugegoda",parent_region_id:4},
    {id:9,name:"Peradeniya",parent_region_id:6},
    ];
    
    const provinces = locations.filter(e => !e.parent_region_id);
    
    const districts = locations.filter(e => provinces.some(p => p.id == e.parent_region_id));
    
    const cities = locations.filter(e => !provinces.includes(e) && !districts.includes(e));
    
    console.log(provinces);
    console.log(districts);
    console.log(cities);