Sortering var en opmærksomhed for computerforskere fra tidligt. Der var mange algoritmer der kom ind og faldt ud af brug, og stadig i dag skubber nye algoritmer grænserne for ydeevne. Som sprog på højt niveau implementerer du ikke sorteringsalgoritmer i Rubin hvis du er interesseret i ydelse og desuden sortering Arrays og andre samlinger er endnu flere ting, Ruby gør for dig.
Teknisk set er sortering et job, der håndteres af modulet Enumerable. Modulet Enumerable er det, der binder alle typer samlinger i Ruby sammen. Det håndterer iterering over samlinger, sortering, gennemgang og finde visse elementer osv. Hvordan Enumerable sorterer en samling er lidt af et mysterium, eller i det mindste skal det forblive sådan. Den egentlige sorteringsalgoritme er irrelevant, det eneste, du behøver at vide, er, at objekter i samlingen sammenlignes ved hjælp af "rumskibsoperatør."
"Rumskibsoperatøren" tager to objekter, sammenligner dem og returnerer derefter -1, 0 eller 1. Det er lidt vagt, men operatøren selv har ikke en meget veldefineret opførsel. Lad os tage numeriske objekter for eksempel. Hvis du har to numeriske objekter
-en og bog evaluere a <=> b, hvad vil udtrykket evaluere til? I tilfælde af Numerics er det let at fortælle. Hvis a er større end b, vil den være -1, hvis de er ens, vil den være 0, og hvis b er større end a, vil den være 1. Dette bruges til at fortælle sorteringsalgoritmen, hvilket af de to objekter der skal gå først i matrix. Bare husk, at hvis venstrehåndsoperand skal komme først i matrixen, skal den evaluere til -1, hvis højre hånd skal være først, skal den være 1, og hvis det ikke betyder noget, skal den være 0.Det følger ikke altid sådanne ryddelige regler. Hvad sker der, hvis du bruger denne operatør på to objekter af forskellige typer? Du får sandsynligvis en undtagelse. Hvad sker der, når du ringer 1 <=> 'abe'? Dette svarer til det, man ringer til 1. <=> ( 'Abe'), hvilket betyder, at den aktuelle metode kaldes på venstre operand og Fixnum # <=> returnerer nul, hvis den højre operand ikke er et tal. Hvis operatøren returnerer nul, giver sorteringsmetoden en undtagelse. Så inden du sorterer arrays, skal du sørge for, at de indeholder objekter, der kan sorteres.
For det andet er rumfartøjsoperatørs faktiske opførsel ikke defineret. Det er kun defineret for nogle af baseklasserne, og for dine tilpassede klasser er det helt op til dig, hvad du vil have dem til at betyde. Hvis du har en Studerende klasse kan du få elever sorteret efter efternavn, fornavn, lønklasse eller en kombination af det. Så vær altid opmærksom på, at rumfartøjsoperatørs opførsel og sortering ikke er godt defineret til andet end basetyperne.
Du har en række numeriske objekter, og du vil gerne sortere dem. Der er to primære metoder til at gøre dette: sortere og sortere!. Den første opretter en kopi af matrixen, sorterer den og returnerer den. Den anden sorterer matrixen på plads.
Det er ret selvforklarende. Så lad os tage det på hak. Hvad hvis du ikke vil stole på rumskiboperatøren? Hvad hvis du vil have en helt anden opførsel? Disse to sorteringsmetoder tager en valgfri blokparameter. Denne blok tager to parametre og skal give værdier, ligesom rumskibets operatør gør: -1, 0 og 1. Så med en matrix vil vi sortere det, så alle værdier, der kan deles med 3, kommer først, og alle andre kommer efter. Den aktuelle orden betyder ikke noget her, bare at de, der kan deles med 3, kommer først.
Hvordan virker det? Bemærk først blokargumentet til sorteringsmetoden. For det andet skal du bemærke modulopdelingen, der er udført på blokparametrene, og genbrugen af rumskiboperatøren. Hvis en er et multiplum af 3, vil moduloen være 0, ellers vil den være 1 eller 2. Da 0 sorterer inden 1 eller 2, er det kun modulet, der betyder noget her. Brug af en blokparameter er især nyttigt i arrays, der har mere end en type element, eller når du vil sortere på brugerdefinerede klasser, der ikke har en defineret rumskiboperator.
Der er en mere sorteringsmetode, kaldet Sorter efter. Du skal dog først forstå oversættelse af matriser og samlinger med kort, inden du tackle sort_by.