Matrici unidimensionali di base
$array = array(3, 5, 2, 8);
Funzioni di ordinamento applicabili:
sort
rsort
asort
arsort
natsort
natcasesort
ksort
krsort
La differenza tra questi è semplicemente se vengono mantenute le associazioni di valori-chiave (le " a
" funzioni), se ordina da basso ad alto o inverso (" r
"), se ordina valori o chiavi (" k
") e come confronta i valori (" nat
" vs. normale). Vedere http://php.net/manual/en/array.sorting.php per una panoramica e collegamenti a ulteriori dettagli.
Matrici multidimensionali, comprese matrici di oggetti
$array = array(
array('foo' => 'bar', 'baz' => 42),
array('foo' => ..., 'baz' => ...),
...
);
Se vuoi ordinare $array
base al tasto "pippo" di ciascuna voce, è necessaria una funzione di confronto personalizzata . Le sort
funzioni precedenti e correlate funzionano su valori semplici che sanno confrontare e ordinare. PHP non "semplicemente" sa cosa fare di un valore complesso come array('foo' => 'bar', 'baz' => 42)
se; quindi devi dirlo.
Per farlo, devi creare un funzione di confronto . Tale funzione accetta due elementi e deve restituire 0
se tali elementi sono considerati uguali, un valore inferiore rispetto a 0
se il primo valore è inferiore e un valore superiore rispetto a 0
se il primo valore è superiore. Questo è tutto ciò che serve:
function cmp(array $a, array $b) {
if ($a['foo'] < $b['foo']) {
return -1;
} else if ($a['foo'] > $b['foo']) {
return 1;
} else {
return 0;
}
}
Spesso, si desidera utilizzare una funzione anonima come callback. Se vuoi usare un metodo o un metodo statico, vedi gli altri modi per specificare un callback in PHP .
Quindi utilizzare una di queste funzioni:
Ancora una volta, differiscono solo per il fatto che mantengano le associazioni valore-chiave e ordinino per valori o chiavi. Leggi la loro documentazione per i dettagli.
Esempio di utilizzo:
usort($array, 'cmp');
usort
prenderà due elementi dall'array e chiamerà la tua cmp
funzione con loro. Così cmp()
sarà chiamato con $a
come array('foo' => 'bar', 'baz' => 42)
e $b
come un altro array('foo' => ..., 'baz' => ...)
. La funzione quindi restituisce a usort
quale dei valori era maggiore o se erano uguali. usort
ripete questo processo passando valori diversi per $a
e $b
finché l'array non viene ordinato. La cmp
funzione verrà chiamata molte volte, almeno quante volte ci sono valori in $array
, con diverse combinazioni di valori per $a
e $b
ogni volta.
Per abituarti a questa idea, prova questo:
function cmp($a, $b) {
echo 'cmp called with $a:', PHP_EOL;
var_dump($a);
echo 'and $b:', PHP_EOL;
var_dump($b);
}
Tutto quello che hai fatto è stato definire un modo personalizzato per confrontare due elementi, questo è tutto ciò di cui hai bisogno. Funziona con tutti i tipi di valori.
A proposito, questo funziona su qualsiasi valore, i valori non devono essere array complessi. Se hai un confronto personalizzato che vuoi fare, puoi farlo anche su un semplice array di numeri.
sort
ordina per riferimento e non restituisce nulla di utile!
Si noti che l'array si ordina sul posto , non è necessario assegnare il valore restituito a nulla. $array = sort($array)
sostituirà l'array con true
, non con un array ordinato. sort($array);
Funziona e basta .
Confronti numerici personalizzati
Se desideri ordinare in base alla baz
chiave, che è numerica, tutto ciò che devi fare è:
function cmp(array $a, array $b) {
return $a['baz'] - $b['baz'];
}
Grazie a The PoWEr oF MATH questo restituisce un valore <0, 0 o> 0 a seconda che $a
sia inferiore a, uguale o maggiore di $b
.
Si noti che questo non funzionerà bene per i float
valori, poiché saranno ridotti a int
e perderanno la precisione. Uso esplicito -1
, 0
e1
restituire i valori invece.
Oggetti
Se hai una matrice di oggetti, funziona allo stesso modo:
function cmp($a, $b) {
return $a->baz - $b->baz;
}
funzioni
Puoi fare tutto ciò di cui hai bisogno all'interno di una funzione di confronto, incluse le funzioni di chiamata:
function cmp(array $a, array $b) {
return someFunction($a['baz']) - someFunction($b['baz']);
}
stringhe
Una scorciatoia per la prima versione di confronto delle stringhe:
function cmp(array $a, array $b) {
return strcmp($a['foo'], $b['foo']);
}
strcmp
fa esattamente quello che ci si aspetta da cmp
qui, ritorna -1
, 0
o 1
.
Operatore di astronave
PHP 7 ha introdotto l' operatore dell'astronave , che unifica e semplifica uguale / più piccolo / più grande dei confronti tra i tipi:
function cmp(array $a, array $b) {
return $a['foo'] <=> $b['foo'];
}
Ordinamento per più campi
Se vuoi ordinare principalmente per foo
, ma se foo
è uguale per due elementi ordina per baz
:
function cmp(array $a, array $b) {
if (($cmp = strcmp($a['foo'], $b['foo'])) !== 0) {
return $cmp;
} else {
return $a['baz'] - $b['baz'];
}
}
Per quelli familiari, questo equivale a una query SQL con ORDER BY foo, baz
.
Vedi anche questa versione abbreviata molto accurata e come creare dinamicamente una simile funzione di confronto per un numero arbitrario di chiavi .
Ordinamento in un ordine manuale, statico
Se vuoi ordinare gli elementi in un "ordine manuale" come "pippo", "bar", "baz" :
function cmp(array $a, array $b) {
static $order = array('foo', 'bar', 'baz');
return array_search($a['foo'], $order) - array_search($b['foo'], $order);
}
Per tutto quanto sopra, se stai usando PHP 5.3 o versioni successive (e dovresti davvero), usa le funzioni anonime per un codice più breve e per evitare di avere un'altra funzione globale fluttuante:
usort($array, function (array $a, array $b) { return $a['baz'] - $b['baz']; });
Ecco come può essere semplice l'ordinamento di un complesso array multidimensionale. Ancora una volta, basti pensare in termini di insegnamento a PHP come dire quale dei due elementi è "maggiore" ; lascia che PHP faccia l'ordinamento effettivo.
Anche per tutto quanto sopra, per passare dall'ordine crescente a quello decrescente basta scambiare gli argomenti $a
e $b
. Per esempio:
return $a['baz'] - $b['baz']; // ascending
return $b['baz'] - $a['baz']; // descending
Ordinamento di un array basato su un altro
E poi c'è il peculiare array_multisort
, che ti consente di ordinare un array in base a un altro:
$array1 = array( 4, 6, 1);
$array2 = array('a', 'b', 'c');
Il risultato atteso qui sarebbe:
$array2 = array('c', 'a', 'b'); // the sorted order of $array1
Usa array_multisort
per arrivarci:
array_multisort($array1, $array2);
A partire da PHP 5.5.0 puoi usare array_column
per estrarre una colonna da un array multidimensionale e ordinare l'array su quella colonna:
array_multisort(array_column($array, 'foo'), SORT_DESC, $array);
A partire da PHP 7.0.0 puoi anche estrarre proprietà da una matrice di oggetti.
Se hai casi più comuni, sentiti libero di modificare questa risposta.