es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Agrupar una matriz por múltiples claves con Array.reduce()

Estoy escribiendo aquí por primera vez y me dieron el siguiente problema. Por ejemplo, tengo la siguiente matriz:

const input = [
  {
    id: 1,
    date: "01-01-2021",
    source: "TT",
    metrics: { conversions: 10, cpl: 3 },
  },
  {
    id: 2,
    date: "01-01-2021",
    source: "TT",
    metrics: { conversions: 15, cpl: 3 },
  },
  {
    id: 3,
    date: "01-01-2021",
    source: "FB",
    metrics: { conversions: 15, cpl: 4 },
  },
  {
    id: 4,
    date: "01-01-2021",
    source: "FB",
    metrics: { conversions: 15, cpl: 4 },
  },
  {
    id: 5,
    date: "02-01-2021",
    source: "TT",
    metrics: { conversions: 5, cpl: 2 },
  },
  {
    id: 6,
    date: "02-01-2021",
    source: "TT",
    metrics: { conversions: 15, cpl: 2 },
  },
  {
    id: 7,
    date: "02-01-2021",
    source: "FB",
    metrics: { conversions: 25, cpl: 1 },
  },
  {
    id: 8,
    date: "02-01-2021",
    source: "FB",
    metrics: { conversions: 30, cpl: 1 },
  },
];

Y necesito obtener una matriz agrupada por fecha y origen, y el valor será la suma de todos sus valores para una fecha específica, por ejemplo, como el resultado a continuación:

const output = [
  {
    date: "01-01-2021",
    TT: 25,
    FB: 30,
  },
  {
    date: "02-01-2021",
    TT: 20,
    FB: 55,
  },
];

En mi solución, encuentro claves y fechas únicas, pero no entiendo qué hacer a continuación. ¿Puedes ayudarme? Código de ejemplo:

const result = input.reduce((acc, current) => {
  const dateItem = acc.find((item) => item.date === current.date);
  const sources = input.map((item) => item.source).filter((value, index, self) => self.indexOf(value) === index);

  if (dateItem) {
    return [...acc.filter((i) => i.date !== current.date), { ...dateItem }];
  }

  return [...acc, { date: current.date }];
}, []);
Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para obtener la salida deseada, es necesario modificar la función reduce para calcular la suma de conversiones y cpl para cada combinación única de fecha y fuente. Esto se puede hacer mediante la iteración de cada elemento en el array input y actualizando la combinación correspondiente de fecha y fuente en el array result.

    Aquí está el código modificado que calcula la salida requerida:

    const result = input.reduce((acc, current) => {
      const dateItem = acc.find((item) => item.date === current.date);
      const sources = input.map((item) => item.source).filter((value, index, self) => self.indexOf(value) === index);
    
      if (dateItem) {
        sources.forEach((source) => {
          if (current.source === source) {
            dateItem[source] = (dateItem[source] || 0) + current.metrics.conversions;
            dateItem[source] = (dateItem[source] || 0) + current.metrics.cpl;
          }
        });
        return [...acc.filter((i) => i.date !== current.date), { ...dateItem }];
      }
    
      const newObj = { date: current.date };
      sources.forEach((source) => {
        if (current.source === source) {
          newObj[source] = current.metrics.conversions + current.metrics.cpl;
        } else {
          newObj[source] = 0;
        }
      });
      return [...acc, newObj];
    }, []);
    

    En este código, hemos agregado un bucle para iterar a través de cada fuente para cada elemento de fecha en el array result. Luego, actualizamos los valores de conversions y cpl para la source en el objeto dateItem. También establecemos el valor predeterminado en 0 si una fuente no está presente para una fecha.

    Finalmente, devolvemos el array acc actualizado con el nuevo objeto dateItem o un nuevo objeto con los campos correctos para la nueva date.

Comments are closed.