Home > Software design >  Group a list of objects in nested arrays javascript
Group a list of objects in nested arrays javascript

Time:10-21

I have an array of objects as below

[
  {
      id: 10,
      regionName: "Europa",
      countryName: "Greece",
      applicationName: "Ramco",
      issueSummary: "No Reported Issues",
      resolutionEta: "",
      status: "UP"
  },
  {
      id: 9,
      regionName: "Asia PAC",
      countryName: "Singapore",
      applicationName: "Reckon",
      issueSummary: "No Reported Issues",
      resolutionEta: "",
      status: "UP"
  },
  {
      id: 7,
      regionName: "Asia PAC",
      countryName: "Thailand",
      applicationName: "Javelin",
      issueSummary: "No Reported Issues",
      resolutionEta: "",
      status: "UP"
  },
  {
      id: 8,
      regionName: "Europa",
      countryName: "Greece",
      applicationName: "Tamco",
      issueSummary: "No Reported Issues",
      resolutionEta: "",
      status: "UP"
  }
]

and I'm trying to group these objects in an array of regions, and each region should have an array of countries and each country should have an array of applications.

{
  regions: [{
    regionName: "Europe",
    countries: [
      {
        countryName: "Greece",
        applications: [
          {
            applicationName: "Ramco",
            issueSummary: "No Reported Issues",
            eta: "",
            status: "UP",
          },
          {
            applicationName: "Tamco",
            issueSummary: "No Reported Issues",
            eta: "",
            status: "UP",
          }
        ]
      },
      {
        countryName: "France",
         applications: [
          {
            applicationName: "Ramco",
            issueSummary: "No Reported Issues",
            eta: "",
            status: "UP",
          },
          {
            applicationName: "Tamco",
            issueSummary: "No Reported Issues",
            eta: "",
            status: "UP",
          }
        ]
      },
    ]
.... and so on
  },

here is what I have so far, it's working only for the regions array. I have a groupBy method and I am using it for regions and countries but this gives me separated arrays, not nested

 ngOnInit(): void {
    this.allRegions$ = this.dataService.getData();

    this.groupData();
  }

  groupData() {
    this.dataService.getData().subscribe(res => {
      this.data = res;
      const regions = this.groupBy('regions', this.data)
      const countries = this.groupBy('countries', regions)
    })
  }

  groupBy(key, array) {
    return array.reduce((all, current) => {
      const existingKey = all.find(existing => existing.key === current[key]);
      console.log(existingKey)
      if (!existingKey) {
        all.push({key: current[key], values: [current]});
      } else {
        existingKey.values.push(current);
      }
      return all;
    }, []);
  }

CodePudding user response:

You could take an abstract approach by using an object as reference to the nested groupuing properties and build the structure as wanted.

This approach works for any depth of grouping just by adding wanted keys to the keys array.

const
    data = [{ id: 10, regionName: "Europa", countryName: "Greece", applicationName: "Ramco", issueSummary: "No Reported Issues", resolutionEta: "", status: "UP" }, { id: 9, regionName: "Asia PAC", countryName: "Singapore", applicationName: "Reckon", issueSummary: "No Reported Issues", resolutionEta: "", status: "UP" }, { id: 7, regionName: "Asia PAC", countryName: "Thailand", applicationName: "Javelin", issueSummary: "No Reported Issues", resolutionEta: "", status: "UP" }, { id: 8, regionName: "Europa", countryName: "Greece", applicationName: "Tamco", issueSummary: "No Reported Issues", resolutionEta: "", status: "UP" }],
    keys = ['regionName', 'countryName'],
    result = data
        .reduce((r, o) => {
            let key;
            keys
                .reduce((t, k) => {
                    ({ [k]: key, ...o } = o);
                    if (!t[key]) {
                        t[key] = { _: [] };
                        t._.push({ [k]: key, children: t[key]._ });
                    }
                    return t[key];
                }, r)
                ._
                .push(o);
            return r;
        }, { _: [] })
        ._;


console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related