Cette question est en fait un tas de problèmes avec votre modèle de données regroupé en un seul. Vous devez commencer à les démêler, un à la fois. Des solutions plus naturelles et intuitives disparaissent lorsque vous essayez de simplifier chaque pièce du puzzle.
Problème 1: vous ne pouvez pas dépendre de l'ordre DB
Vos descriptions du tri de vos données ne sont pas claires.
- Le plus gros problème potentiel est que vous ne spécifiez pas de tri explicite dans votre base de données, via une
ORDER BY
clause. Si ce n'est pas le cas, car cela semble trop cher, votre programme a un bug . Les bases de données sont autorisées à renvoyer les résultats dans n'importe quel ordre si vous n'en spécifiez pas; vous ne pouvez pas en dépendre par coïncidence en renvoyant des données dans l'ordre simplement parce que vous avez exécuté la requête plusieurs fois et que cela ressemble à cela. L'ordre peut changer car les lignes sont réorganisées sur le disque, ou certaines sont supprimées et de nouvelles prennent leur place, ou un index est ajouté. Vous devez spécifier une ORDER BY
clause quelconque. La vitesse ne vaut rien sans correction.
- Il n'est pas clair non plus ce que vous entendez par ordre d'insertion. Si vous parlez de la base de données elle-même, vous devez avoir une colonne qui suit réellement cela, et elle doit être incluse dans votre
ORDER BY
clause. Sinon, vous avez des bugs. Si une telle colonne n'existe pas encore, vous devez en ajouter une. Les options typiques pour des colonnes comme celle-ci seraient une colonne d'horodatage d'insertion ou une clé d'incrémentation automatique. La clé d'incrémentation automatique est plus fiable.
Problème 2: Rendre le tri en mémoire efficace
Une fois que vous assurez - vous qu'il est garanti à retourner les données dans l'ordre que vous attendez, vous pouvez tirer parti de ce fait pour faire en mémoire trie beaucoup plus efficace. Ajoutez simplement une colonne row_number()
oudense_rank()
(ou l'équivalent de votre base de données) à l'ensemble de résultats de votre requête. Maintenant, chaque ligne a un index qui vous donnera une indication directe de ce que l'ordre est censé être, et vous pouvez trier par ceci en mémoire trivialement. Assurez-vous simplement de donner à l'index un nom significatif (comme sortedBySomethingIndex
).
Alto. Désormais, vous n'avez plus à dépendre de l'ordre du jeu de résultats de la base de données.
Problème 3: Avez-vous même besoin de faire ce traitement en code?
SQL est en fait vraiment puissant. C'est un langage déclaratif incroyable qui vous permet de faire beaucoup de transformations et d'agrégations sur vos données. De nos jours, la plupart des bases de données prennent même en charge les opérations entre lignes. On les appelle des fonctions de fenêtre ou d'analyse:
Avez-vous même besoin de mettre vos données en mémoire comme ça? Ou pourriez-vous faire tout le travail dans la requête SQL en utilisant des fonctions de fenêtre? Si vous pouvez faire tout (ou peut-être même juste une partie importante) du travail dans la base de données, fantastique! Votre problème de code disparaît (ou devient beaucoup plus simple)!
Problème 4: tu fais quoi à ça data
?
En supposant que vous ne pouvez pas tout faire dans la base de données, permettez-moi de clarifier les choses. Vous prenez les données sous forme de carte (qui est basée sur des éléments que vous ne souhaitez pas trier), puis vous les itérez dans l' ordre d'insertion et modifiez la carte en place en remplaçant la valeur de certaines clés et en ajoutant les nouvelles?
Je suis désolé, mais qu'est-ce que c'est que ça?
Les appelants ne devraient pas avoir à se soucier de tout cela . Le système que vous avez créé est extrêmement fragile. Il suffit d'une seule erreur stupide (peut-être même faite par vous-même, comme nous l'avons tous fait) pour effectuer un petit changement erroné et le tout s'effondre comme un jeu de cartes.
Voici peut-être une meilleure idée:
- Demandez à votre fonction d'accepter a
List
.
- Il existe plusieurs façons de gérer le problème de commande.
- Appliquer l'échec rapide. Lance une erreur si la liste n'est pas dans l'ordre requis par la fonction. (Remarque: vous pouvez utiliser l'index de tri du problème 2 pour savoir s'il l'est.)
- Créez vous-même une copie triée (à nouveau en utilisant l'index du problème 2).
- Trouvez un moyen de construire la carte elle-même dans l'ordre.
- Construisez la carte dont vous avez besoin en interne pour la fonction, afin que l'appelant n'ait pas à s'en soucier.
- Maintenant, répétez ce que vous avez dans l'ordre et faites ce que vous avez à faire.
- Renvoyer la carte ou la transformer en une valeur de retour appropriée
Une variante possible pourrait être de construire une représentation triée, puis de créer une carte de clé à indexer . Cela vous permettrait de modifier votre copie triée en place, sans créer accidentellement des doublons.
Ou peut-être que cela a plus de sens: se débarrasser du data
paramètre et faire processData
réellement récupérer ses propres données. Vous pouvez alors documenter que vous faites cela car cela a des exigences très spécifiques sur la façon dont les données sont récupérées. En d'autres termes, faites en sorte que la fonction soit propriétaire de l'intégralité du processus, et pas seulement d'une partie de celui-ci; les interdépendances sont trop fortes pour diviser la logique en petits morceaux. (Modifiez le nom de la fonction dans le processus.)
Peut-être que cela ne fonctionnera pas pour votre situation. Je ne sais pas sans tous les détails du problème. Mais je connais un design fragile et déroutant quand j'en entends un.
Sommaire
Je pense que le problème ici est finalement que le diable est dans les détails. Lorsque je commence à rencontrer des problèmes comme celui-ci, c'est généralement parce que j'ai une représentation inappropriée de mes données pour le problème que j'essaie de résoudre. La meilleure solution est de trouver une meilleure représentation , puis mon problème devient simple (peut-être pas facile, mais simple) à résoudre.
Trouvez quelqu'un qui obtient ce point: votre travail consiste à réduire votre problème à un ensemble de problèmes simples et directs. Ensuite, vous pouvez créer du code robuste et intuitif. Parlez-leur. Un bon code et une bonne conception vous font penser que n'importe quel idiot aurait pu les imaginer, car ils sont simples et directs. Peut-être y a-t-il un développeur senior qui a cet état d'esprit auquel vous pouvez parler.