Treci la conținutul principal

Ordonarea unei colecții

Sortarea înseamnă așezarea elementelor unei colecții într-o anumită ordine.

Unele tipuri au o ordine naturală. Numerele sunt ordonate după valoare: 1 vine înaintea lui 2. Șirurile de caractere sunt ordonate alfabetic: "four" vine înaintea lui "one". Pentru orice altceva, sau când vrei o altă ordine, dai o ordine personalizată: o funcție de comparare care se uită la două elemente și spune care dintre ele vine primul.

Funcțiile de sortare din PHP lucrează toate pe loc. Primesc tabloul prin referință, îl modifică și returnează true — nu tabloul sortat. $sorted = sort($words) este o greșeală clasică: $sorted devine true.

  • sort($s) sortează în ordine naturală, cel mai mic primul.
  • rsort($s) sortează în ordine naturală, cel mai mare primul.
  • usort($s, $compare) sortează cu propria ta funcție de comparare.

Toate trei renumerotează cheile cu 0, 1, 2 și așa mai departe.

Pentru a păstra ordinea originală, sortează o copie. În PHP acest lucru este simplu, deoarece tablourile sunt valori: $sorted = $words; îi dă lui $sorted propria copie, iar sortarea ei lasă $words neatins.

O funcție de comparare primește două elemente, $a și $b, și returnează un număr: negativ când $a vine primul, pozitiv când $b vine primul și 0 când sunt egale. Operatorul navă spațială <=> dă exact acest număr: $a <=> $b este -1, 0 sau 1.

Exemplele de mai jos folosesc cuvintele one, two, three, four.


Ordinea naturală

Ordinea naturală este ordinea pe care un tip o are de la sine: numerele după valoare, șirurile de caractere literă cu literă.

sort() așază un tablou în ordine naturală. Pentru ordine descrescătoare există rsort(): aceeași sortare, dar cu cel mai mare element primul. Ambele modifică tabloul pe care îl transmiți, așa că fă-i mai întâi o copie atunci când ai nevoie și de original.

Datele tale proprii, cum ar fi un număr de versiune cu o parte major și o parte minor, nu au o ordine naturală proprie. Îi dai una scriind o funcție de comparare care returnează un număr negativ, zero sau un număr pozitiv. Operatorul navă spațială compară și tablouri întregi, poziție cu poziție, iar prima diferență decide — așadar [$major, $minor] <=> [$otherMajor, $otherMinor] compară mai întâi numerele major, iar numerele minor doar atunci când cele major sunt egale.

Copie sortată

$sorted = $words; copiază tabloul, iar sort() așază copia în ordine alfabetică. Tabloul original $words este afișat după aceea, pentru a arăta că nu s-a modificat.

Prompt
Creează un tablou cu cuvintele one, two, three, four. Copiază-l într-o variabilă nouă și sortează copia cu sort(), astfel încât tabloul original să nu fie modificat. Afișează copia sortată, apoi originalul, fiecare cu implode.
Ieșire: script PHP
Sorted copy

Sortare descrescătoare

rsort() sortează copia cu cel mai mare primul, așa că cuvintele merg de la "two" până la "four".

Prompt
Creează un tablou cu cuvintele one, two, three, four. Copiază-l într-o variabilă nouă și sortează copia în ordine alfabetică descrescătoare cu rsort(). Afișează rezultatul cu implode.
Ieșire: script PHP
Sorted descending

Un tip cu ordinea lui proprie

O versiune este un tablou cu un număr major și un număr minor. compareVersion() compară perechile [major, minor] cu <=>: mai întâi numerele major; doar când acestea sunt egale decid numerele minor. Verificarea compareVersion(...) > 0 răspunde la întrebarea „este prima versiune mai mare?”. json_encode() afișează valorile booleene ca false și true.

Prompt
Stochează numerele de versiune ca tablouri cu cheile major și minor. Scrie o funcție compareVersion care compară două versiuni cu operatorul navă spațială aplicat pe tablourile [major, minor], astfel încât numărul major să decidă primul, iar numărul minor să rezolve egalitatea. Afișează cu json_encode dacă versiunea 1.2 este mai mare decât 1.3, apoi dacă 2.0 este mai mare decât 1.5.
Ieșire: script PHP
A type with its own order

Ordini personalizate

O ordine personalizată este orice ordine pe care o descrii cu o funcție de comparare.

usort() sortează un tablou pe loc cu această funcție. Începând cu PHP 8.0, fiecare sortare din PHP este stabilă: elementele care se compară ca fiind egale își păstrează ordinea originală. Acest lucru contează, de exemplu, la sortarea cuvintelor după lungime.

Cazul de zi cu zi este sortarea după o proprietate a fiecărui element. Pune acea proprietate de ambele părți ale operatorului navă spațială: strlen($a) <=> strlen($b) sortează după lungime.

Pentru ordine descrescătoare, inversează cele două părți: $b <=> $a în loc de $a <=> $b.

Pentru a sorta după un criteriu și apoi după altul, compară două tablouri: [strlen($a), $a] <=> [strlen($b), $b]. Lungimile se compară primele; dacă sunt egale, cuvintele în sine decid egalitatea.

Sortare cu o funcție de comparare

Funcția de comparare returnează strlen($a) <=> strlen($b). Un rezultat negativ înseamnă că $a este mai scurt și vine primul, așa că cuvintele ajung de la cel mai scurt la cel mai lung.

Prompt
Creează un tablou cu cuvintele aaa, bb, c. Sortează-l pe loc cu usort și o funcție de comparare care returnează strlen($a) <=> strlen($b), astfel încât cuvintele mai scurte să fie primele. Afișează rezultatul cu implode.
Ieșire: script PHP
Sort with a compare function

Sortare după lungime

Cuvintele sunt comparate după lungime. "one" și "two" au amândouă 3 litere; sortarea stabilă păstrează "one" înaintea lui "two".

Prompt
Creează un tablou cu cuvintele one, two, three, four. Sortează-le după lungime cu usort și operatorul navă spațială; sortarea este stabilă, așa că cuvintele de aceeași lungime își păstrează ordinea originală. Afișează rezultatul cu implode.
Ieșire: script PHP
Sort by length

Sortare după ultima literă, descrescător

$a[-1] este ultima literă a unui cuvânt: un indice negativ într-un șir de caractere numără de la sfârșit. Literele lui $b și $a sunt comparate în ordine inversată, așa că vine primul cuvântul cu cea mai mare ultimă literă: "four" (r), apoi "two" (o), apoi cele două cuvinte care se termină în „e” în ordinea lor originală.

Prompt
Creează un tablou cu cuvintele one, two, three, four. Sortează-le după ultima literă în ordine descrescătoare cu usort: compară $b[-1] <=> $a[-1]. Afișează rezultatul cu implode.
Ieșire: script PHP
Sort by last letter, descending

Sortare după lungime, apoi alfabetic

Operatorul navă spațială compară tablourile [strlen($a), $a] și [strlen($b), $b] poziție cu poziție. Lungimile decid primele. Când două cuvinte au aceeași lungime, sunt comparate cuvintele în sine, ceea ce le ordonează alfabetic.

Prompt
Creează un tablou cu cuvintele aaa, bb, c, b, a, aa, ccc. Sortează-le mai întâi după lungime și apoi alfabetic cu usort, comparând tablourile [strlen($a), $a] și [strlen($b), $b] cu operatorul navă spațială. Afișează rezultatul cu implode.
Ieșire: script PHP
Sort by length, then alphabetically

Verificarea ordinii de sortare

Uneori vrei doar să afli dacă un tablou este deja sortat, fără să îl sortezi.

PHP nu are o funcție încorporată pentru asta, dar o mică funcție ajutătoare este suficientă: parcurge tabloul, compară fiecare element cu vecinul său din dreapta și returnează false imediat ce o pereche este în ordine greșită. Dă funcției ajutătoare o funcție de comparare opțională și aceeași buclă verifică orice ordine. Pentru ordine descrescătoare transmite fn($a, $b) => $b <=> $a — comparația inversată.

Pentru a verifica ordinea după o singură proprietate, cum ar fi vârsta unui utilizator, compară acea proprietate în interiorul funcției.

Verificare crescătoare și descrescătoare

isSorted() confirmă că 1, 2, 3, 4 sunt în ordine crescătoare. Cu funcția de comparare $b <=> $a confirmă că 4, 3, 2, 1 sunt în ordine descrescătoare.

Prompt
Scrie o funcție ajutătoare isSorted care primește un tablou și o funcție de comparare opțională (implicit: operatorul navă spațială) și returnează false imediat ce un element se compară ca fiind mai mare decât vecinul său din dreapta. Verifică dacă 1, 2, 3, 4 sunt în ordine crescătoare, apoi dacă 4, 3, 2, 1 sunt în ordine descrescătoare, transmițând fn($a, $b) => $b <=> $a. Afișează ambele răspunsuri cu json_encode.
Ieșire: script PHP
Ascending and descending check

Verificarea ordinii după un câmp

Utilizatorii sunt Alice (24), Bob (31) și Charlie (29). Funcția de comparare se uită doar la 'age'. Bob este mai în vârstă decât Charlie, așa că tabloul nu este sortat după vârstă și programul afișează false.

Prompt
Scrie o funcție ajutătoare isSortedBy care primește un tablou și o funcție de comparare și verifică fiecare pereche de vecini. Creează un tablou de utilizatori cu cheile name și age: Alice 24, Bob 31 și Charlie 29. Verifică dacă utilizatorii sunt sortați după vârstă, comparând doar câmpul age, și afișează răspunsul cu json_encode.
Ieșire: script PHP
Check order by a field

Ordinea inversă

Inversarea pune ultimul element primul și primul element ultimul.

Spre deosebire de funcțiile de sortare, array_reverse() nu modifică tabloul pe care i-l dai: returnează o copie inversată, iar originalul își păstrează ordinea.

Copie inversată

Copia creată de array_reverse() este afișată, apoi este afișat originalul pentru a arăta că este neschimbat.

Prompt
Creează un tablou cu cuvintele one, two, three, four. Construiește o copie inversată cu array_reverse, astfel încât originalul să rămână neschimbat. Afișează copia inversată, apoi originalul, fiecare cu implode.
Ieșire: script PHP
Reversed copy

Ordine aleatoare

Amestecarea așază elementele într-o ordine aleatoare.

shuffle() din PHP funcționează ca funcțiile de sortare: pe loc, asupra tabloului pe care îl transmiți. Amestecă o copie dacă ai nevoie și de original.

shuffle() își ia numerele aleatoare din același generator ca mt_rand(). Inițializează acel generator cu mt_srand(seed) și obții aceeași ordine „aleatoare” la fiecare rulare a programului cu acea sămânță. Acest lucru este util pentru teste și pentru exemple ca acesta. Fără o sămânță fixă, ordinea se schimbă la fiecare rulare.

Copie amestecată

mt_srand(14) fixează sămânța, apoi shuffle() amestecă o copie a cuvintelor. Parcurge de la ultima poziție la prima și schimbă fiecare element cu unul ales aleatoriu pe poziția lui sau înaintea ei. Cu această sămânță, rezultatul este two, three, one, four la fiecare rulare.

Prompt
Creează un tablou cu cuvintele one, two, three, four. Inițializează generatorul de numere aleatoare cu mt_srand(14), copiază tabloul într-o variabilă nouă și amestecă copia cu shuffle(). Afișează copia amestecată cu implode.
Ieșire: script PHP
Shuffled copy