J'ai le tableau suivant:
arr = arr.filter((e, index, self) => index === self.findIndex((t) => ( t.id === intent.id && t.lastUpdate > e.lastUpdate )) )
J'ai besoin de filtrer le tableau en fonction du même ID, mais aussi de vérifier l'horodatage "lastUpdate" et de ne conserver que les nouvelles entrées. Le résultat devrait être:
[ {"id": 456, "lastUpdate": 1545269320}, {"id": 123, "lastUpdate": 1552184795} ]
J'ai essayé ce qui suit:
let arr = [ {"id": 123, "lastUpdate": 1543229793}, {"id": 456, "lastUpdate": 1545269320}, {"id": 123, "lastUpdate": 1552184795} ]
Cependant, cela filtre tout pour moi et le le tableau résultant est vide. Je pense que quelque chose ne va pas avec la dernière partie de && t.lastUpdate> e.lastUpdate
ci-dessus.
Merci beaucoup pour vos conseils!
4 Réponses :
Vous pouvez y parvenir en recherchant les éléments qui n'ont pas d'élément2 où la mise à jour a été ultérieure
arr.filter(item => { return !arr.some(item2 => item.id === item2.id && item.lastUpdate < item2.lastUpdate) });
Ce que fait ce code est:
Pour chaque élément dans le tableau, il regarde si dans le tableau il y a un élément avec le même identifiant où le lastUpdate est supérieur au sien. S'il y en a un, il renvoie true (Array.some renvoie un booléen). Nous annulons cette valeur et l'utilisons pour filtrer.
Belle idée de combiner des négatifs "arr.some" et "arr.filter"! Fonctionne en effet, merci pour la réponse rapide!
Vous pouvez le faire étape par étape en convertissant en un ensemble, en triant puis en obtenant le premier élément pour chaque identifiant:
let arr = [ {"id": 123, "lastUpdate": 1543229793}, {"id": 456, "lastUpdate": 1545269320}, {"id": 123, "lastUpdate": 1552184795} ] // Get the ids by making a set of ids and then converting to array let ids = [ ...new Set(arr.map((e) => e.id)) ]; // Sort the original by lastUpdate descending arr.sort((a, b) => b.lastUpdate - a.lastUpdate); // Get array of first item from arr by id let res = ids.map(id => arr.find((e) => e.id == id)); console.log(res);
Salut, si vous cherchez une solution performante vous pouvez utiliser un objet :)
let arr = [{"id": 123,"lastUpdate": 1543229793}, {"id": 456,"lastUpdate": 1545269320}, {"id": 123, "lastUpdate": 1552184795}]; let newArr = {} arr.forEach(el => { if(!newArr[el.id] || newArr[el.id].lastUpdate < el.lastUpdate){ newArr[el.id] = el } }) console.log(Object.values(newArr));
L'ajout de ceci comme réponse acceptée, en raison de meilleures performances.
L'approche de Silvio emballée en code réutilisable, réduit le problème de l'OP à par exemple quelque chose comme ça ...
.as-console-wrapper { max-height: 100%!important; top: 0; }
function collectUniqueItemByIdWithMostRecentUpdate (collector, item, idx, arr) { const store = collector.store; const storedItem = store[item.id]; if (!storedItem || (storedItem.lastUpdate < item.lastUpdate)) { store[item.id] = item; } if (idx >= (arr.length - 1)) { collector.list = Object.values(store); } return collector; } let arr = [ {"id": 123, "lastUpdate": 1543229793}, {"id": 456, "lastUpdate": 1555269320}, {"id": 123, "lastUpdate": 1552184795}, {"id": 456, "lastUpdate": 1545269320}, {"id": 123, "lastUpdate": 1553229793} ]; console.log(arr.reduce(collectUniqueItemByIdWithMostRecentUpdate, { store: {}, list: [] }).list);