Matrizes unidimensionais básicas
$array = array(3, 5, 2, 8);
Funções de classificação aplicáveis:
sort
rsort
asort
arsort
natsort
natcasesort
ksort
krsort
A diferença entre eles é apenas se as associações de valor-chave são mantidas (as " a
" funções), se classifica de baixo para alto ou reverso (" r
"), se classifica valores ou chaves (" k
") e como compara valores (" nat
" vs. normal). Veja http://php.net/manual/en/array.sorting.php para uma visão geral e links para mais detalhes.
Matrizes multidimensionais, incluindo matrizes de objetos
$array = array(
array('foo' => 'bar', 'baz' => 42),
array('foo' => ..., 'baz' => ...),
...
);
Se você deseja classificar $array
pela tecla 'foo' de cada entrada, precisa de uma função de comparação personalizada . As sort
funções acima e relacionadas funcionam com valores simples que eles sabem comparar e classificar. O PHP simplesmente não "sabe" o que fazer com um valor complexo como esse array('foo' => 'bar', 'baz' => 42)
; então você precisa contar.
Para fazer isso, você precisa criar uma função de comparação . Essa função usa dois elementos e deve retornar 0
se esses elementos forem considerados iguais, um valor menor que 0
se o primeiro valor for menor e um valor maior que 0
se o primeiro valor for maior. É tudo o que é necessário:
function cmp(array $a, array $b) {
if ($a['foo'] < $b['foo']) {
return -1;
} else if ($a['foo'] > $b['foo']) {
return 1;
} else {
return 0;
}
}
Freqüentemente, você desejará usar uma função anônima como retorno de chamada. Se você deseja usar um método ou método estático, consulte as outras maneiras de especificar um retorno de chamada no PHP .
Você então usa uma destas funções:
Novamente, eles diferem apenas se mantêm associações de valores-chave e classificam por valores ou chaves. Leia a documentação deles para obter detalhes.
Exemplo de uso:
usort($array, 'cmp');
usort
pegará dois itens da matriz e chamará sua cmp
função com eles. Assim cmp()
será chamado com $a
como array('foo' => 'bar', 'baz' => 42)
e $b
como outro array('foo' => ..., 'baz' => ...)
. A função então retorna para usort
qual dos valores foi maior ou se eles foram iguais. usort
repete esse processo passando valores diferentes para $a
e $b
até que a matriz seja classificada. A cmp
função será chamada muitas vezes, pelo menos quantas vezes houver valores $array
, com diferentes combinações de valores para $a
e $b
sempre.
Para se acostumar com essa ideia, tente o seguinte:
function cmp($a, $b) {
echo 'cmp called with $a:', PHP_EOL;
var_dump($a);
echo 'and $b:', PHP_EOL;
var_dump($b);
}
Tudo o que você fez foi definir uma maneira personalizada de comparar dois itens, é tudo o que você precisa. Isso funciona com todos os tipos de valores.
A propósito, isso funciona com qualquer valor, os valores não precisam ser matrizes complexas. Se você deseja fazer uma comparação personalizada, também pode fazê-lo em uma matriz simples de números.
sort
classifica por referência e não retorna nada útil!
Observe que a matriz é classificada no local , não é necessário atribuir o valor de retorno a nada. $array = sort($array)
substituirá a matriz por true
, não por uma matriz classificada. Apenas sort($array);
funciona.
Comparações numéricas personalizadas
Se você deseja classificar pela baz
chave, que é numérica, tudo que você precisa fazer é:
function cmp(array $a, array $b) {
return $a['baz'] - $b['baz'];
}
Graças ao valor de MATH, isso retorna um valor <0, 0 ou> 0, dependendo de se $a
é menor que, igual ou maior que $b
.
Observe que isso não funcionará bem para float
valores, pois eles serão reduzidos a uma int
e perderão precisão. Use explícita -1
, 0
e 1
valores de retorno em seu lugar.
Objetos
Se você possui uma matriz de objetos, funciona da mesma maneira:
function cmp($a, $b) {
return $a->baz - $b->baz;
}
Funções
Você pode fazer qualquer coisa dentro de uma função de comparação, incluindo funções de chamada:
function cmp(array $a, array $b) {
return someFunction($a['baz']) - someFunction($b['baz']);
}
Cordas
Um atalho para a primeira versão de comparação de cadeias:
function cmp(array $a, array $b) {
return strcmp($a['foo'], $b['foo']);
}
strcmp
é exatamente o que se espera cmp
aqui, ele retorna -1
, 0
ou 1
.
Operador de nave espacial
O PHP 7 introduziu o operador de nave espacial , que unifica e simplifica igual / menor / maior que as comparações entre os tipos:
function cmp(array $a, array $b) {
return $a['foo'] <=> $b['foo'];
}
Classificando por vários campos
Se você deseja classificar principalmente por foo
, mas se foo
for igual para dois elementos, classifique por baz
:
function cmp(array $a, array $b) {
if (($cmp = strcmp($a['foo'], $b['foo'])) !== 0) {
return $cmp;
} else {
return $a['baz'] - $b['baz'];
}
}
Para aqueles familiarizados, isso é equivalente a uma consulta SQL com ORDER BY foo, baz
.
Veja também esta versão simplificada e simples de como criar uma função de comparação dinamicamente para um número arbitrário de chaves .
Classificando em uma ordem estática manual
Se você deseja classificar os elementos em uma "ordem manual", como "foo", "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);
}
Por todas as razões acima, se você estiver usando PHP 5.3 ou superior (e realmente deveria), use funções anônimas para obter um código mais curto e evitar que outra função global flutue:
usort($array, function (array $a, array $b) { return $a['baz'] - $b['baz']; });
É assim que a classificação de uma matriz multidimensional complexa pode ser simples. Novamente, pense em termos de ensinar PHP como saber qual dos dois itens é "maior" ; deixe o PHP fazer a classificação real.
Também para todas as opções acima, para alternar entre ordem crescente e decrescente, basta trocar os argumentos $a
e $b
. Por exemplo:
return $a['baz'] - $b['baz']; // ascending
return $b['baz'] - $a['baz']; // descending
Classificando uma matriz com base em outra
E há o peculiar array_multisort
, que permite classificar um array com base em outro:
$array1 = array( 4, 6, 1);
$array2 = array('a', 'b', 'c');
O resultado esperado aqui seria:
$array2 = array('c', 'a', 'b'); // the sorted order of $array1
Use array_multisort
para chegar lá:
array_multisort($array1, $array2);
A partir do PHP 5.5.0, você pode usar array_column
para extrair uma coluna de uma matriz multidimensional e classificar a matriz nessa coluna:
array_multisort(array_column($array, 'foo'), SORT_DESC, $array);
A partir do PHP 7.0.0, você também pode extrair propriedades de uma matriz de objetos.
Se você tiver casos mais comuns, sinta-se à vontade para editar esta resposta.