Je travaille sur une application angulaire. J'ai le tableau suivant.
[ { "Name": "Jack", "IncomingTime": "2020-06-19T11:02+00:00", "Outgoingtime": "2020-06-19T11:07+00:00", }, { "Name": "Mary", "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T11:07+00:00", }, { "Name": "jolly", "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T11:07+00:00", }, { "Name": "Jack", "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T11:07+00:00", }, { "Name": "Maria", "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T11:17+00:00", }, { "Name": "Maria", "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T12:53+00:00", }, { "Name": "Jack", "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T11:07+00:00", } ]
Je veux réaliser un tableau unique. Je veux trier les éléments de ce tableau de telle sorte qu'il devrait d'abord trier tous les éléments par ordre alphabétique par nom. Si les noms sont identiques, je souhaite trier par heure d'arrivée. Par exemple, la personne avec "Nom ':" jack' se produit trois fois, puis Jack avec l'heure d'arrivée anticipée doit être placé dans le tableau, c'est-à-dire avec "2020-06-19T11: 02 + 00: 00" et reste deux éléments de "jack" ils ont le même temps entrant et sortant sont ignorés (puisque nous en avons déjà inclus un avec le début IncomingTime dans le tableau). Si avec "Name" et "IncomingTime" sont également les mêmes par exemple pour "Maria", il n'y a que deux éléments et "Name", "IncomingTime" sont les mêmes alors je veux garder l'élément avec le temps de sortie précoce c'est-à-dire l'élément qui devrait être dans le tableau résultant doit être de "OutgointTime": "2020-06-19T11: 17 + 00: 00" et l'autre avec "OutgointTime" 12:53 est ignoré. Comment puis-je y parvenir?
4 Réponses :
Pas sûr, mais quelque chose comme ça ..
aa.sort( function (a, b) { // try names if (a["Name"] < b["Name"]) return -1; else if (a["Name"] > b["Name"]) return 1; // if names are equal compare IncomingTime if (a["IncomingTime"] < b["IncomingTime"]) return -1; else if (a["IncomingTime"] > b["IncomingTime"]) return 1; return 0; } );
J'ai essayé ceci, le problème auquel je suis confronté avec Arrays.sort si par exemple pour Jack il va trier mais d'abord il gardera Jack avec l'heure d'arrivée précoce, puis deux autres éléments "Jack" avec le même temps d'élément aussi, comme je veux un tableau unique selon la description mentionnée par moi en question. Je suis à court d'idées sur la façon de modifier cela pour obtenir un tableau selon la description
Vous pouvez simplement utiliser Lodash Trier par fonction. _. Sortby code> laissera appliquer plusieurs niveaux de niveau de niveau. Vérifiez cela. P> p>
C'est une chose incroyable. Pourriez-vous simplement m'aider à obtenir un tableau unique comme je l'ai mentionné dans ma description du problème. Je trouve très difficile de faire ça avec cette charge
Dans TypeScript, le code de Mayank Gupta est comme
a.sort((a:any, b:any) => a.Name>b.Name?1:a.Name<b.Name?-1: a.IncomingTime>b.IncomingTime?1: a.IncomingTime<b.IncomingTime?-1: a.Outgoingtime>b.Outgoingtime?1: a.Outgoingtime<b.Outgoingtime?-1:0)
Sort changez le tableau: developer.mozilla.org / fr-FR / docs / Web / JavaScript / Reference /… . Eh bien, c'est vrai que retourne le tableau trié aussi, c'est la raison pour laquelle vous voyez habituellement b = a.sort (.....), mais le tableau lui-même est trié
J'obtiens des doublons en utilisant ceci
Jetez un coup d'œil à la réponse de Nicholas
Compte tenu de vos données brutes,
const sortedData = rawData.sort( (x,y) => x.Name < y.Name ? -1 // sort by name : x.Name > y.Name ? +1 // : x.IncomingTime < y.IncomingTime ? -1 // then by incoming time : x.IncomingTime > y.IncomingTime ? +1 // : x.Outgoingtime < y.Outgoingtime ? -1 // then by outgoing time : x.Outgoingtime > y.Outgoingtime ? +1 : 0 // both items compare equal ); const map = new Map(); for (const entry of sortedData) { const value = map.get(entry.Name); if (!value) { map.set(entry.Name, entry); } } const uniqueData = Array.from(map.values());
Pour obtenir ce que vous voulez, nous procédons comme suit:
Commencez par trier les données brutes par Nom
, puis IncomingTime
, puis OutgoingTime
.
Ensuite, nous parcourons les données maintenant triées et gardons une trace de l'élément précédent que nous avons visité. Chaque fois que nous voyons une rupture dans la clé de tri primaire (un changement de nom), nous savons que nous avons l'élément souhaité (par exemple, l'enregistrement du nom donné avec le temps d'entrée le plus bas) et nous le poussons sur l'ensemble des éléments uniques. Nous savons que nous avons un saut de séquence si
Cela nous amène à cette solution.
[ { "Name": "Jack", "IncomingTime": "2020-06-19T11:02+00:00", "Outgoingtime": "2020-06-19T11:07+00:00" }, { "Name": "Maria", "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T11:17+00:00" }, { "Name": "Mary", "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T11:07+00:00" }, { "Name": "jolly", "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T11:07+00:00" } ]
Ce qui produit
const sortedData = rawData.sort( (x,y) => x.Name < y.Name ? -1 // sort by name : x.Name > y.Name ? +1 // : x.IncomingTime < y.IncomingTime ? -1 // then by incoming time : x.IncomingTime > y.IncomingTime ? +1 // : x.Outgoingtime < y.Outgoingtime ? -1 // then by outgoing time : x.Outgoingtime > y.Outgoingtime ? +1 : 0 // both items compare equal ); const uniqueData = []; let prev; for (const curr of sortedData) { if ( !prev || curr.Name !== prev.Name ) { uniqueData.push(curr); } prev = curr; } console.log(JSON.stringify(uniqueData,undefined,2));
Une solution sans doute plus simple peut être d'utiliser Map
. Cela accomplit la même chose (saisissez la 1ère entrée pour chaque nom dans la liste ordonnée). La bonne chose à propos de Map
est que, contrairement aux objets simples, les données sont garanties d'être renvoyées dans l'ordre d'insertion, donc l'ordre de la liste triée est conservé:
const rawData = [ { "Name": "Jack", "IncomingTime": "2020-06-19T11:02+00:00", "Outgoingtime": "2020-06-19T11:07+00:00", }, { "Name": "Mary", "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T11:07+00:00", }, { "Name": "jolly", "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T11:07+00:00", }, { "Name": "Jack", "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T11:07+00:00", }, { "Name": "Maria", "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T11:17+00:00", }, { "Name": "Maria", "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T12:53+00:00", }, { "Name": "Jack", "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T11:07+00:00", } ];
hey simple deux-points enfin de la sorte. Avez-vous manqué quelque chose ici ou il n'y a qu'un seul deux-points dans cette ligne?
Pourriez-vous également expliquer votre code après la méthode de tri et aussi je veux renvoyer le tableau de résultats après les opérations, comment puis-je le faire dans ce code?
Les deux points simples ne sont que des expressions ternaires imbriquées: developer.mozilla .org / en-US / docs / Web / JavaScript / Reference /…
Mais que se passe-t-il lorsque le nom est le même et que l'entrée est différente et si l'entrée est également la même mais que la sortie est différente
Tous les enregistrements partageant le même nom sont triés par heure d'arrivée. Tous les enregistrements portant le même nom et l'heure d'entrée sont triés par heure de sortie. Le code parcourt ensuite cette liste ordonnée et prend le premier enregistrement pour chaque nom. Ainsi, pour chaque nom, vous obtiendrez cet enregistrement avec le temps d'entrée le plus bas. S'il y a des multiples avec le même nom et la date d'entrée la plus basse, vous obtiendrez l'enregistrement avec la date de sortie la plus basse.
J'ai obtenu les bons résultats avec ceci mais je ne comprends pas pour (const curr of sortedData) {if (! Prev || curr.Name! == prev.Name) {uniqueData.push (curr); } prev = curr; Dans ce code, je peux voir que vous ne comparez que des noms, mais comment cela se compare-t-il sur la base du temps entrant et sortant? Désolé, mais je ne comprends toujours pas que vous pourriez s'il vous plaît expliquer comment cela se passe si vous ne comparez que des noms
Parce que la liste est triée , nous n'avons pas besoin de regarder les heures entrantes / sortantes: nous l'avons fait, nous avons trié la liste. Tout ce qui nous importe, c'est d'identifier le changement de nom. Le premier enregistrement rencontré pour chaque nom est l'enregistrement souhaité. En ce qui concerne la comparaison, le test de ! Prev
ne réussira que pour le 1er enregistrement, lorsque
prev` est indéfini
(cela étant un Valeur "falsy". Le deuxième test, prev.Name! == curr.Name
réussit lorsque le nom change entre les enregistrements.
salut, ce code est parfaitement bien. Mais y a-t-il un moyen de réaliser la même chose sans utiliser la boucle?
Vous pourriez probablement utiliser reduction ()
... mais tout ce que cela accomplit est de cacher la boucle. À un moment donné, vous devez parcourir la collection et choisir ce dont vous avez besoin.
Vous pouvez vérifier cette réponse Stackoverflow.com/questions/21857647/... a>
Pour moi, cette option Arrays.sort n'est pas d'une grande aide car lorsque deux éléments similaires sont trouvés, il conserve les deux mais je veux un tableau unique selon la condition mentionnée ci-dessus