Dada esta matriz:
$inventory = array(
array("type"=>"fruit", "price"=>3.50),
array("type"=>"milk", "price"=>2.90),
array("type"=>"pork", "price"=>5.43),
);
Gostaria de classificar $inventory
os elementos por preço para obter:
$inventory = array(
array("type"=>"pork", "price"=>5.43),
array("type"=>"fruit", "price"=>3.50),
array("type"=>"milk", "price"=>2.90),
);
Como posso fazer isso?
Respostas:
Você está certo, a função que você está procurando é
array_multisort()
.Aqui está um exemplo retirado diretamente do manual e adaptado ao seu caso:
fonte
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:
Ou um tipo descendente como este:
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):E observe também que
<=>
, o operador da nave espacial,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 é quePHP 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: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 passamosusort
precisa retornar números inteiros parausort
que funcionem corretamente: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.fonte
uasort
. Depois de analisar os documentos, no entanto, esta resposta ainda está correta neste caso . No exemplo do OP, a matriz a ser classificada possui índices numéricos seqüenciais em vez de índices de string, portanto,usort
é mais apropriado. O usouasort
em uma matriz indexada seqüencialmente resultará em uma matriz classificada que não é ordenada por seus índices numéricos, de modo que o primeiro elemento visto em umforeach
loop não seja$your_array[0]
, o que é improvável que seja um comportamento desejável.Enquanto outros sugeriram corretamente o uso de
array_multisort()
, por algum motivo, nenhuma resposta parece reconhecer a existência dearray_column()
, o que pode simplificar bastante a solução. Então, minha sugestão seria:fonte
Como seus elementos de matriz são matrizes com chaves de seqüência de caracteres, sua melhor aposta é definir uma função de comparação personalizada. É bem rápido e fácil de fazer. Tente o seguinte:
Produz o seguinte:
fonte
uasort( $inventory, function ($a, $b) { if ( $a==$b ) return 0; else return ($a > $b) ? -1 : 1; });
usort
parece mais apropriado do queuasort
para classificar uma matriz com chaves numéricas seqüenciais. Terminar com uma matriz em que o primeiro elemento está no índice1
e o segundo elemento está no índice0
é um comportamento estranho e uma armadilha certa para pessoas que não estão familiarizadas com os detalhes das matrizes do PHP;usort
fornece a saída que você esperaria intuitivamente.Eu terminei com isso:
Basta chamar a função, passando a matriz e o nome do campo da matriz de segundo nível. Gostar:
fonte
Você pode usar
usort
com função anônima, por exemplofonte
strnatcmp
, destinado a comparar seqüências de caracteres, parece funcionar bem aqui. Aparentemente, a "ordem natural" implementada inclui a classificação de seqüências numéricas numericamente em vez de lexicamente.saídas:
fonte
De Classificar uma matriz de matrizes associativas pelo valor da chave fornecida no php :
O uasort ( http://php.net/uasort ) permite que você classifique uma matriz por sua própria função definida. No seu caso, isso é simples:
fonte
cmp
função aqui está errada. Ele 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", mas retornatrue
oufalse
. Parece, extraordinariamente, funcionar - talvez porque a implementação atual deusort
e amigos trate os casos "menor que" e "igual a" de forma idêntica - mas não conte com isso continuando trabalhando em futuras versões do PHP. Se eles tentarem fazer com que as classificações sejam estáveis (ou seja, não se movam desnecessariamente em elementos iguais), isso será interrompido.usort
seria mais apropriado do queuasort
aqui, poisuasort
preserva a associação entre chaves e valores, o que é confuso e inesperado ao ser utilizado com uma matriz numérica sequencial. Por exemplo, os índices$array
acima após a chamadauasort
são 2, 0 e 1, nessa ordem. A menos que você, por algum motivo, queira isso, provavelmente ficará mais confortável com o usousort
, o que reindexa a matriz e também a reordena.Foi testado em 100.000 registros: Tempo em segundos (calculado pela função microtime). Somente para valores exclusivos na classificação de posições-chave.
Solução de função de @Josh Davis: tempo gasto: 1.5768740177155
Solução da mina: Tempo gasto: 0.094044923782349
Solução:
fonte
Eu uso
uasort
assimfonte
Esta função é reutilizável:
Por padrão, ele funciona bem em valores de seqüência de caracteres, mas você precisará subverter o retorno de chamada para uma função de comparação de números se todos os seus valores forem números.
fonte
usortarr
mas depois chama emuasort
vez deusort
; talvez um pouco confuso. O último é - no caso de uma matriz seqüencial com índices numéricos, como o exibido na pergunta - provavelmente o que você realmente deseja.Você pode tentar definir sua própria função de comparação e usar usort .
fonte
Aqui está um método que eu encontrei há muito tempo e limpei um pouco. Isso funciona muito bem e pode ser alterado rapidamente para aceitar objetos também.
Para alterar o método para classificar objetos, basta alterar a seguinte linha:
$tempArray[] = strtolower( $value[ $sortByKey ] );
para$tempArray[] = strtolower( $value->$sortByKey );
Para executar o método, basta fazer
sortArray($inventory,'price','ASC');
fonte
array_multisort
) ou a minha (comusort
) e parece não oferecer vantagens sobre elas em troca.fonte
tente isto:
fonte
Função dinâmica completa Eu pulei aqui para a classificação associativa de matrizes e encontrei essa incrível função em http://php.net/manual/en/function.sort.php . Essa função é muito dinâmica, classificada em ordem crescente e decrescente com a chave especificada.
Função simples para classificar uma matriz por uma chave específica. Mantém a associação do índice
fonte
fonte
tente isto:
para referência, veja o seguinte: http://php.net/manual/en/function.asort.php
veja vários sinalizadores de classificação aqui: http://www.php.net/manual/en/function.sort.php
fonte