Estoy intentando tomar una serie de resultados y reducirlos a una sola matriz.
Los datos son:
const data = [ { profileid: '1', points: 25, winner: true }, { profileid: '2', points: 15, winner: false }, { profileid: '3', points: 18, winner: false }, { profileid: '1', points: 15, winner: true }, { profileid: '2', points: 18, winner: false }, { profileid: '3', points: 25, winner: false }, ] Estoy intentando resumir todos los puntos por ID de usuario (lo he logrado) y también resumir la cantidad de veces que el winner === true en cada objeto
Resultados previstos
[ { profileid: '1', points: 40, wins: 1 }, { profileid: '2', points: 33, wins: 0 }, { profileid: '3', points: 43, wins: 1 }, ]Actualmente no puedo contar la suma de resultados "verdaderos" en cada objeto. Además, estoy devolviendo un objeto en lugar de una matriz.
Retazo
const data = [ { profileid: '1', points: 25, winner: true }, { profileid: '2', points: 15, winner: false }, { profileid: '3', points: 18, winner: false }, { profileid: '1', points: 15, winner: false }, { profileid: '2', points: 18, winner: false }, { profileid: '3', points: 25, winner: true }, ] const result = data.reduce((acc, cur) => ({ ...acc, [cur.profileid]: { profileid: cur.profileid, points: cur.points + (acc[cur.profileid] ? acc[cur.profileid].points : 0), wins: cur.winner ? acc[cur.profile] ? acc[cur.profile].wins + 1 : 0 : acc[cur.profile] ? acc[cur.profile].wins : 0, }, }), [] ) console.log(result)Aplicar la misma lógica para los points puede dar algo como:
wins: cur.winner ? ((acc[cur.profileid]?.wins || 0) + 1) : (acc[cur.profileid]?.wins || 0), ¿Empezamos comprobando si el winner actual es true
1 ( || 0 ) por primera vez donde las wins no existenacc[cur.profileid]?.wins (también una alternativa si la primera vez es false ) const data = [ { profileid: '1', points: 25, winner: true }, { profileid: '2', points: 15, winner: false }, { profileid: '3', points: 18, winner: false }, { profileid: '1', points: 15, winner: false }, { profileid: '2', points: 18, winner: false }, { profileid: '3', points: 25, winner: true }, ] const result = data.reduce((acc, cur) => ({ ...acc, [cur.profileid]: { wins: cur.winner ? ((acc[cur.profileid]?.wins || 0) + 1) : (acc[cur.profileid]?.wins || 0), profileid: cur.profileid, points: cur.points + (acc[cur.profileid] ? acc[cur.profileid].points : 0), }, }), [] ) console.log(result) Dicho esto, personalmente prefiero un simple for y un solo if para obtener un código más legible:
Por favor considere este ejemplo:
result vacíodatadata si es necesariopoints y wins valores const data = [ { profileid: '1', points: 25, winner: true }, { profileid: '2', points: 15, winner: false }, { profileid: '3', points: 18, winner: false }, { profileid: '1', points: 15, winner: false }, { profileid: '2', points: 18, winner: false }, { profileid: '3', points: 25, winner: true }, ]; const result = {}; for (let i in data) { // Create current profileId object if (!result[data[i].profileid]) { result[data[i].profileid] = { wins: 0, points: 0, profileid: +data[i].profileid }; } // Bump points/wins values result[data[i].profileid].points += data[i].points; result[data[i].profileid].wins += +data[i].winner; } console.log(result);Puede sumar las wins de la misma manera que suma los points :
const data = [ { profileid: '1', points: 25, winner: true }, { profileid: '2', points: 15, winner: false }, { profileid: '3', points: 18, winner: false }, { profileid: '1', points: 15, winner: true }, { profileid: '2', points: 18, winner: false }, { profileid: '3', points: 25, winner: true }, ] const result = data.reduce((acc, cur) => ({ ...acc, [cur.profileid]: { profileid: cur.profileid, points: cur.points + (acc[cur.profileid] ? acc[cur.profileid].points : 0), wins: cur.winner + (acc[cur.profileid] ? acc[cur.profileid].wins : 0) }, }), [] ) console.log(result) También puede simplificar las wins de esta manera:
wins: !!(acc[cur.profileid]?.wins) + cur.winner
En caso de que acc[cur.profileid]?.wins devuelva undefined ,
puede convertirlo a un booleano por !! o Boolean() para evitar obtener NaN