Search code examples
javascriptjsonangulartypescriptangular8

Angular 8 - How to filter nested JSON and return result in new array


I am getting below JSON from API response inside the fetchdataFromAPI function.

I want to find distinct regions from all children of the below JSON objects and need to create new a filtered array of objects same as my expected output.

I have the below code with JSON from which I tried to get my expected output but anyhow it is returning only objects of the first children, not all children objects.

Can anyone please help me to correct my code and provide my expected response from the below function?

fetchdataFromAPI() {
    const data = [
      {
        "name": "Africa",
        "children": [
          {
            "name": "Test1",
            "region": "1UL Africa"
          },
          {
            "name": "Test2",
            "region": "South Africa",
          },
          {
            "name": "Test3",
            "region": "1UL Africa",
          }
        ]
      },
      {
        "name": "Europe",
        "children": [
          {
            "name": "Test4",
            "region": "1UL Africa"
          },
          {
            "name": "Test5",
            "region": "Test Europe"
          }
        ]
      }
    ];
    this.dataService.setBUSubRegionList(this.processRegion(data));
  }

 processRegion(buRegionList) {    
    const list = [];  
    for (const buReg of buRegionList) {
      const tempBu = buReg;
      if (buReg.children) {
        let i = 0;
        for (const buRegion of buReg.children) {        
          if (!buRegion.region) {          
            tempBu.children.splice(i, 1);
          }
          i++;
        }
      }
      list.push(tempBu);
    } 
    return list;
  }

Below is my expected output from the above JSON.

newData = [
   {
      "name": "Test1", 
      "region": "1UL Africa"        
   },
   {
      "name": "Test2",
      "region": "South Africa",           
   },
   {
      "name": "Test5",
      "region": "Test Europe"       
   },
];

Solution

  • Solution 1

    From the attached code, didn't see you perform any filtering and add the filtered data into the returned list.

    function processRegion(buRegionList: any[]) {
        const list = [];
    
        for (const buReg of buRegionList) {
            if (buReg.children) {
                for (const buRegion of buReg.children) {
                    if (list.findIndex(x => x.region == buRegion.region) == -1) {
                        list.push(buRegion);
                    }
                }
            }
        }
    
        return list;
    }
    

    Demo Solution 1 @ Typescript Playground


    Solution 2

    Besides, you may work with .reduce() to perform the group by region as key-value pair. Then return the values from key-value pair as list.

    function processRegion(buRegionList: any[]) {
        const list = buRegionList.reduce((acc, cur) => {
            for (let child of cur.children) {
                if (!(child.region in acc)) {
                    acc[child.region] = child;
                }
            }
            
            return acc;
        }, {});
    
        return Object.values(list);
    }
    

    Demo Solution 2 @ Typescript Playground