Estoy recibiendo una matriz de objetos como este
[ { "payload":{ "correlation":{ "metadata":{ "customerId":"12345", "project":"Project One" } } } }, { "payload":{ "correlation":{ "metadata":{ "customerId":"12345", "project":"Project Two" } } } }, { "payload":{ "correlation":{ "metadata":{ "customerId":"12345", "project":"Project Two" } } } }, { "payload":{ "correlation":{ "metadata":{ "customerId":"54323", "project":"Project One" } } } } ]Lo que estoy tratando de hacer es contar todos los ID de cliente únicos por proyecto. Entonces, para los datos anteriores, esperaría
Project One: 2 Project Two: 1 //because 12345 is shown twice for Project Two, we only want unique so count it as 1Entonces puedo hacer los conteos usando un mapa, algo como esto
const lutProjects = new Map(); Object.entries(data).forEach(([key, value]) => { const project = value?.payload?.correlation?.metadata?.project; const custId = value?.payload?.correlation?.metadata?.customerId; lutProjects.set(project, (lutProjects.get(project) || 0) + 1); });Sin embargo, esto no maneja identificaciones únicas para cada proyecto, por lo que las salidas 2 y 2.
¿Cómo puedo manejar también identificaciones únicas por proyecto?
He creado un JSFiddle
Gracias
Puede intentar una solución rápida con el siguiente fragmento
let data = [{"payload":{"correlation":{"metadata":{"customerId":"12345","project":"Project One"}}}},{"payload":{"correlation":{"metadata":{"customerId":"12345","project":"Project Two"}}}},{"payload":{"correlation":{"metadata":{"customerId":"12345","project":"Project Two"}}}},{"payload":{"correlation":{"metadata":{"customerId":"54323","project":"Project One"}}}}] data = Array.from(new Set(data.map(f => f.payload.correlation.metadata.project))).map(d => { return { [d]: [...new Set(data.filter(f => f.payload.correlation.metadata.project === d).map(c => c.payload.correlation.metadata.customerId))].length } }); console.log(data);Use el método de reducción en combinación con una matriz de identificadores únicos para cada proyecto, luego use la longitud en esa matriz para conocer el recuento final. Aquí está mi propuesta:
const arr = [ { "payload":{ "correlation":{ "metadata":{ "customerId":"12345", "project":"Project One" } } } }, { "payload":{ "correlation":{ "metadata":{ "customerId":"12345", "project":"Project Two" } } } }, { "payload":{ "correlation":{ "metadata":{ "customerId":"12345", "project":"Project Two" } } } }, { "payload":{ "correlation":{ "metadata":{ "customerId":"54323", "project":"Project One" } } } } ] const cb = (accumulator, { payload }) => { const { project, customerId } = payload.correlation.metadata if (!accumulator[project]) { return { ...accumulator, [project]: [customerId] } } else if (accumulator[project] && accumulator[project].indexOf(customerId) === -1) { return { ...accumulator, [project]: [...accumulator[project], customerId] } } else return accumulator } const initialAccumulator = {} const result1 = arr.reduce(cb, initialAccumulator) const result2 = Object.keys(result1).map(key => ({ [key]: result1[key].length })) console.log(result2)Si usa reduce() para crear un objeto con el project como clave y el valor como una matriz que contiene el ID de customerId , podemos usar includes() para verificar si este ID de customerId ya se conoce, y solo agregarlo a la matriz si no .
Luego, podemos usar un segundo reduce() para cambiar la matriz ow customerId a la length de la matriz:
const data = [{"payload":{"correlation":{"metadata":{"customerId":"12345", "project":"Project One"} } } }, {"payload":{"correlation":{"metadata":{"customerId":"12345", "project":"Project Two"} } } }, {"payload":{"correlation":{"metadata":{"customerId":"12345", "project":"Project Two"} } } }, {"payload":{"correlation":{"metadata":{"customerId":"54323", "project":"Project One"} } } } ]; let res = data.reduce((prev, cur) => { const { customerId, project } = cur.payload.correlation.metadata; if (!prev[project]) prev[project] = []; if (!prev[project].includes(customerId)) { prev[project].push(customerId); } return prev; }, {}); res = Object.keys(res).reduce((prev, cur) => ({ ...prev, [cur]: res[cur].length }), {}); console.log(res); { "Project One": 2, "Project Two": 1 }