Home > Enterprise >  How to group a json object based on the equal key values using JavaScript
How to group a json object based on the equal key values using JavaScript

Time:03-29

I have the following json object in javascript:

employeeRecords = [
    {
    "empID" : "7002",
    "company" : "Google",
    "group" : "Chrome",
    "id" : "D-2005",
    "city" : "New York",
    "date" : "2018-05-01"
    },
    {
    "empID" : "9002",
    "company" : "Apple",
    "group" : "iPhone",
    "id" : "D-2014",
    "city" : "Singapore"
    "date": "2019-07-15"
    },
    {
    "empID" : "7002",
    "company" : "Google",
    "group" : "Android",
    "id" : "H-2007",
    "city" : "London"
    "date": "2018-05-01"
    },
    {
    "empID" : "7002"
    "company" : "Google",
    "group" : "Android",
    "id" : "K-2007",
    "city" : "London"
    "date": "2019-06-18"
    },
    {
    "empID" : "9002",
    "company" : "Apple",
    "group" : "Laptop",
    "id" : "N-2012",
    "city" : "Japan"
    "date": "2019-07-15"
    }
]

The requirement is to group this json object, if the empID, company and the date is equal. If those key values are equal then the group field should be concatenated. I need to get this using JavaScript.

So the result should be like the following:

employeeRecords = [
    {
    "empID" : "7002",
    "company" : "Google",
    "group" : "Chrome-Android",
    "id" : "D-2005",
    "city" : "New York",
    "date" : "2018-05-01"
    },
    {
    "empID" : "9002",
    "company" : "Apple",
    "group" : "iPhone-Laptop",
    "id" : "D-2014",
    "city" : "Singapore"
    "date": "2019-07-15"
    },
    {
    "empID" : "7002"
    "company" : "Google",
    "group" : "Android",
    "id" : "K-2007",
    "city" : "London"
    "date": "2019-06-18"
    }
]

Any help to achieve this in JavaScript please? Thanks in advance.

CodePudding user response:

The first solution that comes to my mind is to add an element to a new list according to a control while traversing all the elements with the Array.prototype.forEach method.

const fixedRecords = [];
employeeRecords.forEach(record => {
  let index = fixedRecords.findIndex(fr => fr.empID === record.empID && fr.date === record.date && fr.company === record.company)
  if(index !== -1) {
    fixedRecords[index] = {
       ...fixedRecords[index],
       group: fixedRecords[index].group   '-'   record.group 
    }
  }else {
    fixedRecords.push(record);
  }
})

This method will work. However, consider this; The findIndex function running for each list element means that this list will run for the number of elements for each element count (n * n). Therefore, if your list is large, it will not be very performant.

CodePudding user response:

This uses reduce() and a JS object to compute the groups and will run in O(n) which is (at least for large arrays) considerably quicker than an implementation with includes(), find() or other nested loop approaches which take O(n²).

Just a note: I am not sure why you would want id and city in the output as this is meaningless information as this is the information for the first employee of a group and may or may not be true for all employees in that group, hence it's useless information that could potentially be confusing as it looks like a legitimate employee.

const employeeRecords = [
  {
    empID: "7002",
    company: "Google",
    group: "Chrome",
    id: "D-2005",
    city: "New York",
    date: "2018-05-01",
  },
  {
    empID: "9002",
    company: "Apple",
    group: "iPhone",
    id: "D-2014",
    city: "Singapore",
    date: "2019-07-15",
  },
  {
    empID: "7002",
    company: "Google",
    group: "Android",
    id: "H-2007",
    city: "London",
    date: "2018-05-01",
  },
  {
    empID: "7002",
    company: "Google",
    group: "Android",
    id: "K-2007",
    city: "London",
    date: "2019-06-18",
  },
  {
    empID: "9002",
    company: "Apple",
    group: "Laptop",
    id: "N-2012",
    city: "Japan",
    date: "2019-07-15",
  },
];

const resultObj = employeeRecords.reduce((acc, emp) => {
  // concatenate the key (all criteria together build the key)
  const key = `${emp.empID}-${emp.company}-${emp.date}`;
  // if we already have a value with that key, add the group of the current employee
  if(acc.hasOwnProperty(key)) acc[key].group  = `-${emp.group}`;
  // if we don't have a value with that key add that employee
  else acc[key] = emp;
  return acc;
}, {});

const result = Object.values(resultObj);
console.log(result);

  • Related