Tengo una matriz de objetos que son un registro de las acciones realizadas por los usuarios. Este es un ejemplo de cómo se ve la matriz:
[ { "timestamp": "2022-07-14T14:53:32.925Z", "action": "Action 1", "user": "User A" }, { "timestamp": "2022-07-13T14:53:32.925Z", "action": "Action 1", "user": "User A" }, { "timestamp": "2022-07-12T14:53:32.925Z", "action": "Action 1", "user": "User A" }, { "timestamp": "2022-07-11T14:53:32.925Z", "action": "Action 2", "user": "User A" }, { "timestamp": "2022-07-10T14:53:32.925Z", "action": "Action 2", "user": "User A" }, { "timestamp": "2022-07-09T14:53:32.925Z", "action": "Action 1", "user": "User A" }, { "timestamp": "2022-07-08T14:53:32.925Z", "action": "Action 1", "user": "User A" }, { "timestamp": "2022-07-07T14:53:32.925Z", "action": "Action 3", "user": "User B" } ]El resultado que estoy tratando de lograr es que la matriz debería ser:
[ { "timestamp": "2022-07-14T14:53:32.925Z", "action": "Action 1", "user": "User A" }, { "timestamp": "2022-07-11T14:53:32.925Z", "action": "Action 2", "user": "User A" }, { "timestamp": "2022-07-09T14:53:32.925Z", "action": "Action 1", "user": "User A" }, { "timestamp": "2022-07-07T14:53:32.925Z", "action": "Action 3", "user": "User B" } ]La matriz está en orden de tiempo.
No quiero agrupar todos los duplicados, por ejemplo, toda la "acción 1" del "Usuario A", solo si ocurrieron uno tras otro, guarde el más reciente
¡Cualquier sugerencia sería muy apreciada, TIA!
Podemos usar Array.reduce() para agregar cada elemento a nuestra matriz de salida ( acc ) si cumple alguno de los criterios:
Esto debería dar el resultado requerido.
const input = [ { "timestamp": "2022-07-14T14:53:32.925Z", "action": "Action 1", "user": "User A" }, { "timestamp": "2022-07-13T14:53:32.925Z", "action": "Action 1", "user": "User A" }, { "timestamp": "2022-07-12T14:53:32.925Z", "action": "Action 1", "user": "User A" }, { "timestamp": "2022-07-11T14:53:32.925Z", "action": "Action 2", "user": "User A" }, { "timestamp": "2022-07-10T14:53:32.925Z", "action": "Action 2", "user": "User A" }, { "timestamp": "2022-07-09T14:53:32.925Z", "action": "Action 1", "user": "User A" }, { "timestamp": "2022-07-08T14:53:32.925Z", "action": "Action 1", "user": "User A" }, { "timestamp": "2022-07-07T14:53:32.925Z", "action": "Action 3", "user": "User B" } ]; const result = (input.reduce((acc, { timestamp, action, user }) => { const { action: lastAction, user: lastUser, timestamp: lastTimestamp } = acc[acc.length - 1] || {}; if (lastAction !== action || lastUser !== user || lastTimestamp < timestamp) { acc.push({ timestamp, action, user }); } return acc; }, [])); console.log('Result:', result); .as-console-wrapper { max-height: 100% !important; }Suponiendo que la matriz de entrada está ordenada de nueva a antigua. Puede recorrerlos, comparar cada acción con la última acción presente en el resultado. Si tiene el mismo combo de acción/usuario, no lo agregue al resultado. Si no es el mismo usuario/acción, agréguelo al resultado. Repita hasta que haya iterado a través de todas las acciones.
Puede verificar la igualdad de acción/usuario de diferentes maneras. Una forma de hacer esto sería usar su propia función de igualdad personalizada.
const isEqual = (a, b) => a.action === b.action && a.user === b.user; // you can then compare 2 actions using isEqual(actionA, actionB) function solution(actions) { const last = array => array[array.length - 1]; const isEqual = (a, b) => a.action === b.action && a.user === b.user; const output = []; for (const inputAction of actions) { const outputAction = last(output) || {}; // skip if the action/user combination is the same if (isEqual(inputAction, outputAction)) continue; output.push(inputAction); } return output; } console.log(solution([ { "timestamp": "2022-07-14T14:53:32.925Z", "action": "Action 1", "user": "User A" }, { "timestamp": "2022-07-13T14:53:32.925Z", "action": "Action 1", "user": "User A" }, { "timestamp": "2022-07-12T14:53:32.925Z", "action": "Action 1", "user": "User A" }, { "timestamp": "2022-07-11T14:53:32.925Z", "action": "Action 2", "user": "User A" }, { "timestamp": "2022-07-10T14:53:32.925Z", "action": "Action 2", "user": "User A" }, { "timestamp": "2022-07-09T14:53:32.925Z", "action": "Action 1", "user": "User A" }, { "timestamp": "2022-07-08T14:53:32.925Z", "action": "Action 1", "user": "User A" }, { "timestamp": "2022-07-07T14:53:32.925Z", "action": "Action 3", "user": "User B" } ]));Puede usar la sort de la función javascrip para su matriz:
const log = [ { "timestamp": "2022-07-14T14:53:32.925Z", "action": "Action 1", "user": "User A" }, { "timestamp": "2022-07-13T14:53:32.925Z", "action": "Action 1", "user": "User A" }, { "timestamp": "2022-07-12T14:53:32.925Z", "action": "Action 1", "user": "User A" }, { "timestamp": "2022-07-11T14:53:32.925Z", "action": "Action 2", "user": "User A" }, { "timestamp": "2022-07-10T14:53:32.925Z", "action": "Action 2", "user": "User A" }, { "timestamp": "2022-07-09T14:53:32.925Z", "action": "Action 1", "user": "User A" }, { "timestamp": "2022-07-08T14:53:32.925Z", "action": "Action 1", "user": "User A" }, { "timestamp": "2022-07-07T14:53:32.925Z", "action": "Action 3", "user": "User B" } ] const uniqArray = (arr) => { return arr.filter((elem, pos, self) => { return self.findIndex((item) => item.timestamp == elem.timestamp) == pos }) } const uniqueLog = uniqArray(log, (item) => item.timestamp) const sortedLog = uniqueLog.sort((row) => new Date(row.timestamp).getTime()) console.log({ sortedLog })