Das Sortieren war für Informatiker von Anfang an ein Hauptanliegen. Da waren viele Algorithmen das kam in und fiel aus dem Gebrauch und noch heute verschieben neue Algorithmen die Grenzen der Leistung. Als Hochsprache implementieren Sie keine Sortieralgorithmen in Rubin Wenn Sie Wert auf Leistung legen und außerdem auf das Sortieren Arrays und andere Sammlungen sind noch mehr Dinge, die Ruby für Sie erledigt.
Technisch gesehen ist das Sortieren ein Job, der vom Enumerable-Modul ausgeführt wird. Das Enumerable-Modul verbindet alle Arten von Sammlungen in Ruby miteinander. Es behandelt das Durchlaufen von Sammlungen, das Sortieren, Durchsuchen und Finden bestimmter Elemente usw. Wie Enumerable eine Sammlung sortiert, ist ein Rätsel, oder sollte es zumindest bleiben. Der eigentliche Sortieralgorithmus ist irrelevant. Sie müssen lediglich wissen, dass Objekte in der Sammlung mit dem "Raumschiffoperator" verglichen werden.
Der "Raumschiffoperator" nimmt zwei Objekte, vergleicht sie und gibt dann -1, 0 oder 1 zurück. Das ist etwas vage, aber der Bediener selbst hat kein sehr genau definiertes Verhalten. Nehmen wir zum Beispiel numerische Objekte. Wenn Sie zwei numerische Objekte haben
ein und bund bewerten a <=> b, wie wird der Ausdruck ausgewertet? Im Fall von Numerics ist es leicht zu sagen. Wenn a größer als b ist, ist es -1, wenn sie gleich sind, ist es 0 und wenn b größer als a ist, ist es 1. Dies wird verwendet, um dem Sortieralgorithmus mitzuteilen, welches der beiden Objekte zuerst in das Objekt aufgenommen werden soll Array. Denken Sie daran, dass der linke Operand, wenn er im Array an erster Stelle stehen soll, mit -1 ausgewertet werden soll, wenn die rechte Hand an erster Stelle stehen soll, sollte er 1 sein, und wenn es keine Rolle spielt, sollte er 0 sein.Es folgt nicht immer so ordentlichen Regeln. Was passiert, wenn Sie diesen Operator für zwei Objekte unterschiedlichen Typs verwenden? Sie werden wahrscheinlich eine Ausnahme bekommen. Was passiert, wenn Sie anrufen? 1 <=> 'Affe'? Dies entspricht dem Anruf 1. <=> ('Affe')Dies bedeutet, dass die eigentliche Methode auf dem aufgerufen wird links Operand und Fixnum # <=> Gibt nil zurück, wenn der rechte Operand keine Zahl ist. Wenn der Operator nil zurückgibt, löst die Sortiermethode eine Ausnahme aus. Stellen Sie daher vor dem Sortieren von Arrays sicher, dass sie Objekte enthalten, die sortiert werden können.
Zweitens ist das tatsächliche Verhalten des Raumschiffoperators nicht definiert. Es ist nur für einige der Basisklassen definiert, und für Ihre benutzerdefinierten Klassen liegt es ganz bei Ihnen, was sie bedeuten sollen. Wenn Sie eine haben Schüler Klasse Sie können Schüler nach Nachname, Vorname, Klassenstufe oder einer Kombination davon sortieren lassen. Beachten Sie daher immer, dass das Verhalten des Raumschiffoperators und der Sortierung nur für die Basistypen genau definiert ist.
Sie haben ein Array numerischer Objekte und möchten diese sortieren. Hierfür gibt es zwei Hauptmethoden: Sortieren und Sortieren!. Der erste erstellt eine Kopie des Arrays, sortiert es und gibt es zurück. Der zweite sortiert das Array an Ort und Stelle.
Das ist ziemlich selbsterklärend. Nehmen wir es also noch einmal auf. Was ist, wenn Sie sich nicht auf den Raumschiffbetreiber verlassen möchten? Was ist, wenn Sie ein völlig anderes Verhalten wünschen? Diese beiden Sortiermethoden verwenden einen optionalen Blockparameter. Dieser Block akzeptiert zwei Parameter und sollte genau wie der Raumschiffoperator Werte liefern: -1, 0 und 1. Wenn ein Array gegeben ist, möchten wir es so sortieren, dass alle durch 3 teilbaren Werte an erster Stelle stehen und alle anderen danach. Die tatsächliche Reihenfolge spielt hier keine Rolle, nur dass diejenigen, die durch 3 teilbar sind, an erster Stelle stehen.
Wie funktioniert das? Beachten Sie zunächst das Blockargument für die Sortiermethode. Zweitens beachten Sie die Modulo-Unterteilungen, die an den Blockparametern vorgenommen wurden, und die Wiederverwendung des Raumschiffoperators. Wenn eins ein Vielfaches von 3 ist, ist das Modulo 0, andernfalls ist es 1 oder 2. Da 0 vor 1 oder 2 sortiert wird, ist hier nur das Modulo von Bedeutung. Die Verwendung eines Blockparameters ist besonders nützlich in Arrays mit mehr als einem Elementtyp oder wenn Sie nach benutzerdefinierten Klassen sortieren möchten, für die kein Raumschiffoperator definiert ist.
Es gibt noch eine Sortiermethode namens sortiere nach. Sie sollten jedoch zuerst die Übersetzung von Arrays und Sammlungen mit Map verstehen, bevor Sie sort_by in Angriff nehmen.