Hice una pregunta similar aquí Transform an Array into an Object usando .reduce() , sin embargo, estoy tratando de encontrar una solución alternativa con findIndex.
Estos datos de entrada:
const reports = [ { dateOfReport: "11-01-2021", userId: "id1", userMetric: { first_metric: 10, second_metric: 15 }, }, { dateOfReport: "11-01-2021", userId: "id2", userMetric: { first_metric: 9, second_metric: 14 }, }, { dateOfReport: "12-01-2021", userId: "id1", userMetric: { first_metric: 11, second_metric: 14 }, }, { dateOfReport: "12-01-2021", userId: "id2", userMetric: { first_metric: 16, second_metric: 19 }, }, ];Los datos de salida deben ser:
const output = [ { dateOfReport: "11-01-2021", id1: { first_metric: 10, second_metric: 15 }, id2: { first_metric: 9, second_metric: 14 }, }, { dateOfReport: "12-01-2021", id1: { first_metric: 11, second_metric: 14 }, id2: { first_metric: 16, second_metric: 19 }, }, ];Intenté escribir un código similar a continuación, pero obtengo datos duplicados en la salida. ¿Alguien puede ayudar a resolver este problema?
const groupedReports = reports.reduce((acc, dataItem) => { const nodeIndex = acc.findIndex((item) => item.dateOfReport === dataItem.dateOfReport); const newNode = { date: dataItem.date, [dataItem.userId]: dataItem.userMetric }; console.log("NEW NODE", newNode); return [...acc.slice(0, nodeIndex - 1), newNode, ...acc.slice(nodeIndex + 1)] }, []);Creo que puedes hacer esto:
reports.reduce((pre, cur) => { let index = pre.findIndex(item => item.dateOfReport == cur.dateOfReport) if (index != -1) { pre[index][cur.userId] = cur.userMetric } else { pre.push({ dateOfReport: cur.dateOfReport, [cur.userId]: cur.userMetric }) } return pre }, [])Puede tomar un objeto para agrupar y asignar las nuevas propiedades a la identificación.
const reports = [{ dateOfReport: "11-01-2021", userId: "id1", userMetric: { first_metric: 10, second_metric: 15 } }, { dateOfReport: "11-01-2021", userId: "id2", userMetric: { first_metric: 9, second_metric: 14 } }, { dateOfReport: "12-01-2021", userId: "id1", userMetric: { first_metric: 11, second_metric: 14 } }, { dateOfReport: "12-01-2021", userId: "id2", userMetric: { first_metric: 16, second_metric: 19 } }], result = Object.values(reports.reduce((r, { dateOfReport, userId, userMetric }) => { (r[dateOfReport] ??= { dateOfReport })[userId] = userMetric; return r; }, {})); console.log(result); .as-console-wrapper { max-height: 100% !important; top: 0; }Aquí está mi solución:
const reports = [ { dateOfReport: "11-01-2021", userId: "id1", userMetric: { first_metric: 10, second_metric: 15 }, }, { dateOfReport: "11-01-2021", userId: "id2", userMetric: { first_metric: 9, second_metric: 14 }, }, { dateOfReport: "12-01-2021", userId: "id1", userMetric: { first_metric: 11, second_metric: 14 }, }, { dateOfReport: "12-01-2021", userId: "id2", userMetric: { first_metric: 16, second_metric: 19 }, }, ]; const sortReports = (reports) => { // Array of dates with no duplicates const dates = [...new Set(reports.map(el => el.dateOfReport))]; // Replace each date with an array of reports that are relevant to the date // Reduce each array of reports into an object with your desired format const newReports = dates .map(date => reports .filter(report => report.dateOfReport === date) .reduce(el => ({ dateOfReport: el.dateOfReport, [el.userId]: el.userMetric }))); return newReports; } console.log(sortReports(reports));