Le tri était une préoccupation des informaticiens dès le début. Il y avait beaucoup algorithmes qui sont entrés et tombés en désuétude et encore aujourd'hui de nouveaux algorithmes repoussent les limites de la performance. Étant un langage de haut niveau, vous n'implémenterez pas d'algorithmes de tri dans Rubis si vous vous souciez de la performance, et en plus du tri Tableaux et d'autres collections sont encore plus de choses que Ruby fait pour vous.
Techniquement, le tri est un travail géré par le module Enumerable. Le module Enumerable est ce qui relie tous les types de collections dans Ruby. Il gère l'itération sur les collections, le tri, la recherche et la recherche de certains éléments, etc. Comment Enumerable trie une collection est un peu mystérieux, ou du moins cela devrait le rester. L'algorithme de tri réel n'est pas pertinent, la seule chose que vous devez savoir est que les objets de la collection sont comparés à l'aide de "l'opérateur du vaisseau spatial".
L '"opérateur de vaisseau spatial" prend deux objets, les compare puis renvoie -1, 0 ou 1. C'est un peu vague, mais l'opérateur lui-même n'a pas un comportement très bien défini. Prenons l'exemple des objets numériques. Si vous avez deux objets numériques
une et bet évaluer a <=> b, à quoi l'expression évaluera-t-elle? Dans le cas de Numerics, c'est facile à dire. Si a est supérieur à b, ce sera -1, s'ils sont égaux ce sera 0 et si b est supérieur à a, ce sera 1. Ceci est utilisé pour indiquer à l'algorithme de tri lequel des deux objets doit aller en premier dans le tableau. N'oubliez pas que si l'opérande de gauche doit venir en premier dans le tableau, il doit être évalué à -1, si la main droite doit être la première, elle doit être 1, et si cela n'a pas d'importance, elle doit être 0.Il ne suit pas toujours de telles règles bien rangées. Que se passe-t-il si vous utilisez cet opérateur sur deux objets de types différents? Vous obtiendrez probablement une exception. Que se passe-t-il lorsque vous appelez 1 <=> 'singe'? Ce sera l'équivalent d'appeler 1. <=> ('Singe'), ce qui signifie que la méthode actuelle est appelée sur le la gauche opérande et Fixnum # <=> renvoie nil si l'opérande de droite n'est pas un numérique. Si l'opérateur retourne nil, la méthode de tri lèvera une exception. Donc, avant de trier les tableaux, assurez-vous qu'ils contiennent des objets qui peuvent être triés.
Deuxièmement, le comportement réel de l'opérateur du vaisseau spatial n'est pas défini. Il n'est défini que pour certaines des classes de base, et pour vos classes personnalisées, c'est à vous de voir ce que vous voulez qu'elles signifient. Si tu as un Étudiant classe, vous pouvez demander aux élèves de trier par nom, prénom, niveau scolaire ou une combinaison de ces éléments. Soyez donc toujours conscient que le comportement de l'opérateur du vaisseau spatial et le tri ne sont pas bien définis pour autre chose que les types de base.
Vous disposez d'un tableau d'objets numériques et vous souhaitez les trier. Il existe deux méthodes principales pour ce faire: Trier et Trier!. Le premier crée une copie du tableau, le trie et le renvoie. Le second trie le tableau en place.
C'est assez explicite. Prenons donc un cran. Et si vous ne voulez pas vous fier à l'opérateur du vaisseau spatial? Et si vous voulez un comportement complètement différent? Ces deux méthodes de tri prennent un paramètre de bloc facultatif. Ce bloc prend deux paramètres et devrait donner des valeurs comme le fait l'opérateur du vaisseau spatial: -1, 0 et 1. Donc, étant donné un tableau, nous voulons le trier de sorte que toutes les valeurs qui sont divisibles par 3 viennent en premier, et toutes les autres viennent après. L'ordre réel n'a pas d'importance ici, juste que ceux divisibles par 3 viennent en premier.
Comment cela marche-t-il? Tout d'abord, notez l'argument bloc de la méthode de tri. Deuxièmement, notez les divisions modulo effectuées sur les paramètres du bloc et la réutilisation de l'opérateur du vaisseau spatial. Si on est un multiple de 3, le modulo sera 0, sinon, ce sera 1 ou 2. Puisque 0 triera avant 1 ou 2, seul le modulo compte ici. L'utilisation d'un paramètre de bloc est particulièrement utile dans les tableaux qui ont plus d'un type d'élément, ou lorsque vous souhaitez trier sur des classes personnalisées qui n'ont pas d'opérateur de vaisseau spatial défini.
Il existe une autre méthode de tri, appelée Trier par. Cependant, vous devez d'abord comprendre la traduction des tableaux et des collections avec map avant de vous attaquer à sort_by.