Tengo el siguiente objeto json en 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" } ]El requisito es agrupar este objeto json, si el empID, la empresa y la fecha son iguales. Si esos valores clave son iguales, el campo de grupo debe concatenarse. Necesito obtener esto usando JavaScript.
Así que el resultado debería ser como el siguiente:
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" } ]¿Alguna ayuda para lograr esto en JavaScript, por favor? Gracias por adelantado.
La primera solución que me viene a la mente es agregar un elemento a una nueva lista de acuerdo con un control mientras recorre todos los elementos con el método Array.prototype.forEach.
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); } })Este método funcionará. Sin embargo, considere esto; La función findIndex que se ejecuta para cada elemento de la lista significa que esta lista se ejecutará para la cantidad de elementos para cada recuento de elementos (n * n). Por lo tanto, si su lista es grande, no tendrá mucho rendimiento.
Esto usa reduce() y un objeto JS para calcular los grupos y se ejecutará en O(n) que es (al menos para arreglos grandes) considerablemente más rápido que una implementación con includes() , find() u otros enfoques de bucle anidado que toman O(n²) .
Solo una nota: no estoy seguro de por qué querría
idycityen la salida, ya que esta es información sin sentido, ya que esta es la información para el primer empleado de un grupo y puede o no ser cierta para todos los empleados en ese grupo, por lo tanto es información inútil que podría ser potencialmente confusa ya que parece un empleado legítimo.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);