PHP 7+
A partir do PHP 7, isso pode ser feito de forma concisa, usando usort
uma função anônima que usa o operador de nave espacial para comparar elementos.
Você pode fazer uma classificação ascendente como esta:
usort($inventory, function ($item1, $item2) {
return $item1['price'] <=> $item2['price'];
});
Ou um tipo descendente como este:
usort($inventory, function ($item1, $item2) {
return $item2['price'] <=> $item1['price'];
});
Para entender como isso funciona, observe que usort
utiliza uma função de comparação fornecida pelo usuário que deve se comportar da seguinte maneira (nos documentos):
A função de comparação deve retornar um número inteiro menor que, igual a ou maior que zero se o primeiro argumento for considerado respectivamente menor que, igual a ou maior que o segundo.
E observe também que <=>
, o operador da nave espacial,
retorna 0 se ambos os operandos forem iguais, 1 se a esquerda for maior e -1 se a direita for maior
o que é exatamente o que usort
precisa. De fato, quase toda a justificativa dada para adicionar <=>
ao idioma em https://wiki.php.net/rfc/combined-comparison-operator é que
faz escrever callbacks ordenação para uso com usort()
mais fácil
PHP 5.3 ou superior
O PHP 5.3 introduziu funções anônimas, mas ainda não possui o operador de nave espacial. Ainda podemos usar usort
para classificar nossa matriz, mas é um pouco mais detalhado e difícil de entender:
usort($inventory, function ($item1, $item2) {
if ($item1['price'] == $item2['price']) return 0;
return $item1['price'] < $item2['price'] ? -1 : 1;
});
Observe que, embora seja bastante comum que comparadores que lidam com valores inteiros retornem apenas a diferença dos valores, por exemplo $item2['price'] - $item1['price']
, não podemos fazer isso com segurança nesse caso. Isso ocorre porque os preços são números de ponto flutuante no exemplo do autor da pergunta, mas a função de comparação para a qual passamos usort
precisa retornar números inteiros para usort
que funcionem corretamente:
Retornar valores não inteiros da função de comparação, como float, resultará em uma conversão interna para inteiro do valor de retorno do retorno de chamada. Portanto, valores como 0,99 e 0,1 serão convertidos em um valor inteiro 0, que comparará esses valores como iguais.
Esta é uma armadilha importante a ser lembrada ao usar usort
no PHP 5.x! Minha versão original desta resposta cometeu esse erro e, no entanto, acumulei dez upvotes em milhares de visualizações, aparentemente sem que ninguém percebesse o bug sério. A facilidade com que idiotas como eu podem estragar as funções do comparador é precisamente o motivo pelo qual o operador de nave espacial mais fácil de usar foi adicionado à linguagem no PHP 7.