0

The objective of this question is to identify a generic solution for a flat structure data to be transformed to a hierarchical structure with the mentioned expected form.

I have an array of objects data in below format:

[
  {"company": "Google", "country": "USA", "employee": "John"},
  {"company": "Amazon", "country": "UK", "employee": "Arya"},
  {"company": "Google", "country": "KSA", "employee": "Cersi"},
  {"company": "Amazon", "country": "USA", "employee": "Tyrion"},
  {"company": "Amazon", "country": "USA", "employee": "Daenarys"},
  {"company": "Google", "country": "KSA", "employee": "Dothrokhi"}
]

need to transform it into the below format:

 {
  "company": [
    {
      "company": "Amazon",
      "country": [
        {
          "country": "UK",
          "employee": [
            "Arya"
          ]
        },
        {
          "country": "USA",
          "employee": [
            "Tyrion",
            "Daenarys"
          ]
        }
      ]
    },
    {
      "company": "Google",
      "country": [
        {
          "country": "KSA",
          "employee": [
            "Cersi",
            "Dothrokhi"
          ]
        },
        {
          "country": "USA",
          "employee": [
            "John"
          ]
        }
      ]
    }
  ]
}

what would be the best approach to be used : array.reduce() or array.map(). or do we have a better and different approach

need to handle duplicates as well.

The expected solution should handle a generic scenario if possible as described below :

Consider n level of tree structure as expected result. Here at the moment, it's 3 levels : company -> country -> employee. In get neral it could be like : level1 -> level2 -> level3 -> level4 -> level5 -> -> leveln

Thanks for the pointers shared in comments.

I got this answer on further research, but it is not as generic as I intended to achieve.

I wanted to find a generic method to help me generate n levels of hierarchical data from a flat structure.

const data = [{
    company: "Google",
    country: "USA",
    employee: "John"
  },
  {
    company: "Amazon",
    country: "UK",
    employee: "Arya"
  },
  {
    company: "Google",
    country: "KSA",
    employee: "Cersi"
  },
  {
    company: "Amazon",
    country: "USA",
    employee: "Tyrion"
  },
  {
    company: "Amazon",
    country: "USA",
    employee: "Daenarys"
  },
  {
    company: "Google",
    country: "KSA",
    employee: "Dothrokhi"
  }
];

// Log to console
// console.log(data);

let res = Object.entries(
    data.reduce((result, {
      company,
      country,
      employee
    }) => {
      const groupedSubtypeList = (result[company] ??= []);

      if (country !== null) {
        groupedSubtypeList.push({
          country,
          employee
        });
      }
      return result;
    }, {})
  )
  // additional mapping over the reduce result's entries.
  .map(([company, countries]) => {
    const companyItem = {
      company: company
    };
    if (countries.length >= 1) {
      // companyItem.country = countries.map((country) => ({
      //   country: country.country,
      //   employee: country.employee
      // }));
      // console.log(countries);

      let temp = Object.entries(
        countries.reduce((result, {
          country,
          employee
        }) => {
          const groupedSubtypeList = (result[country] ??= []);

          if (employee !== null) {
            groupedSubtypeList.push(employee);
          }
          return result;
        }, {})
      ).map(([country, employee]) => {
        const countryItem = {
          country: country
        };
        if (employee.length >= 1) {
          countryItem.employee = employee.map((employee) => employee);
        }
        return countryItem;
      });
      companyItem.country = temp;
    }
    return companyItem;
  });

console.log(res);

Reference : https://stackoverflow.com/a/72091962/4672396

1 Answers1

0

Thanks for the pointers shared in comments.

I got this answer on further research, but it is not as generic as I intended to achieve.

I wanted to find a generic method to help me generate n levels of hierarchical data from a flat structure.

const data = [{
    company: "Google",
    country: "USA",
    employee: "John"
  },
  {
    company: "Amazon",
    country: "UK",
    employee: "Arya"
  },
  {
    company: "Google",
    country: "KSA",
    employee: "Cersi"
  },
  {
    company: "Amazon",
    country: "USA",
    employee: "Tyrion"
  },
  {
    company: "Amazon",
    country: "USA",
    employee: "Daenarys"
  },
  {
    company: "Google",
    country: "KSA",
    employee: "Dothrokhi"
  }
];

// Log to console
// console.log(data);

let res = Object.entries(
    data.reduce((result, {
      company,
      country,
      employee
    }) => {
      const groupedSubtypeList = (result[company] ??= []);

      if (country !== null) {
        groupedSubtypeList.push({
          country,
          employee
        });
      }
      return result;
    }, {})
  )
  // additional mapping over the reduce result's entries.
  .map(([company, countries]) => {
    const companyItem = {
      company: company
    };
    if (countries.length >= 1) {
      // companyItem.country = countries.map((country) => ({
      //   country: country.country,
      //   employee: country.employee
      // }));
      // console.log(countries);

      let temp = Object.entries(
        countries.reduce((result, {
          country,
          employee
        }) => {
          const groupedSubtypeList = (result[country] ??= []);

          if (employee !== null) {
            groupedSubtypeList.push(employee);
          }
          return result;
        }, {})
      ).map(([country, employee]) => {
        const countryItem = {
          country: country
        };
        if (employee.length >= 1) {
          countryItem.employee = employee.map((employee) => employee);
        }
        return countryItem;
      });
      companyItem.country = temp;
    }
    return companyItem;
  });

console.log(res);

Reference : https://stackoverflow.com/a/72091962/4672396