Sortering var en uppmärksamhet för datavetare från början av. Där var många algoritmer som kom in och föll ur användning och fortfarande idag är det nya algoritmer som driver prestandan. Som språk på hög nivå kommer du inte att implementera sorteringsalgoritmer i Rubin om du bryr dig om prestanda och dessutom sortering arrayer och andra samlingar är ännu fler saker som Ruby gör för dig.
Tekniskt sett är sortering ett jobb som hanteras av modulen Enumerable. Modulen Enumerable är vad som binder alla typer av samlingar i Ruby tillsammans. Den hanterar iterering över samlingar, sortering, genomblick och hitta vissa element, etc. Hur många sorterar en samling är lite av ett mysterium, eller åtminstone borde det vara så. Den faktiska sorteringsalgoritmen är irrelevant, det enda du behöver veta är att objekt i samlingen jämförs med "rymdskeppsoperatören."
"Rymdskeppsoperatören" tar två objekt, jämför dem och returnerar sedan -1, 0 eller 1. Det är lite vagt, men operatören själv har inte ett särskilt väl definierat beteende. Låt oss ta numeriska objekt till exempel. Om du har två numeriska objekt
en och boch utvärdera a <=> b, vad kommer uttrycket att utvärdera till? När det gäller Numerics är det lätt att berätta. Om a är större än b blir det -1, om de är lika kommer det att vara 0 och om b är större än a blir det 1. Detta används för att berätta sorteringsalgoritmen vilket av de två objekten som ska gå först i array. Kom bara ihåg att om den vänstra operanden ska komma först i matrisen bör den utvärderas till -1, om den högra handen ska vara först ska den vara 1, och om den inte spelar någon roll bör den vara 0.Det följer inte alltid så snygga regler. Vad händer om du använder denna operatör på två objekt av olika typer? Du får antagligen ett undantag. Vad händer när du ringer 1 <=> 'apa'? Detta kommer att motsvara samtal 1. <=> ( 'Apa'), vilket betyder att den faktiska metoden kallas på vänster operand och Fixnum # <=> returnerar noll om den högra operanden inte är en siffra. Om operatören returnerar noll kommer sorteringsmetoden att göra ett undantag. Så innan du sorterar matriser måste du se till att de innehåller objekt som kan sorteras.
För det andra är rymdskeppsoperatörens faktiska beteende inte definierat. Det är bara definierat för några av basklasserna, och för dina anpassade klasser är det helt upp till dig vad du vill att de ska betyda. Om du har en Studerande klassen kan du få studentens sortering efter efternamn, förnamn, betygsnivå eller en kombination av det. Så var alltid medveten om att rymdskeppsoperatörens beteende och sortering inte är väl definierat för något annat än bastyperna.
Du har ett antal numeriska objekt och du vill sortera dem. Det finns två primära metoder för att göra detta: sortera och sortera!. Den första skapar en kopia av matrisen, sorterar och returnerar den. Den andra sorterar matrisen på plats.
Det är ganska självförklarande. Så låt oss ta upp det. Tänk om du inte vill lita på rymdskeppsoperatören? Tänk om du vill ha ett helt annat beteende? Dessa två sorteringsmetoder tar en valfri blockparameter. Det blocket tar två parametrar och bör ge värden precis som rymdskeppsoperatören gör: -1, 0 och 1. Så med tanke på en matris vill vi sortera det så att alla värden som kan delas med 3 kommer först och alla andra kommer efter. Den faktiska ordningen spelar ingen roll här, bara att de som kan delas med 3 kommer först.
Hur fungerar detta? Notera först blockargumentet till sorteringsmetoden. För det andra, notera modulodivisionerna som görs på blockparametrarna och återanvändningen av rymdskeppsoperatören. Om en är en multipel av 3, kommer modulo att vara 0, annars blir den 1 eller 2. Eftersom 0 kommer att sortera före 1 eller 2, är det bara modulen som spelar roll här. Att använda en blockparameter är särskilt användbart i matriser som har mer än en typ av element, eller när du vill sortera på anpassade klasser som inte har en definierad rymdskeppsoperatör.
Det finns en mer sorteringsmetod, kallad sortera efter. Du bör dock först förstå översättningen av matriser och samlingar med karta innan du tar itu med sort_by.