objetos - ¿Cómo puedo ordenar una matriz multidimensional por uno de los campos de la matriz interna en PHP?
ordenar array por value php (6)
Necesita usar usort , una función que ordena arrays a través de una función definida por el usuario. Algo como:
function cmp($a, $b)
{
if ($a["price"] == $b["price"]) {
return 0;
}
return ($a["price"] < $b["price"]) ? -1 : 1;
}
usort($yourArray,"cmp")
Supongamos que tengo una matriz que imita una tabla de base de datos. Cada elemento de matriz representa una fila, y dentro de cada fila hay otra matriz que contiene los nombres y valores de campo.
Array
(
[0] => Array
(
[name] => ''Sony TV''
[price] => 600.00
)
[1] => Array
(
[name] => ''LG TV''
[price] => 350.00
)
[2] => Array
(
[name] => ''Samsung TV''
[price] => 425.00
)
}
Lo que quiero hacer es ordenar las filas (elementos de la matriz externa) por precio. A continuación se muestra un ejemplo de lo que quiero lograr:
Array
(
[0] => Array
(
[name] => ''LG TV''
[price] => 350.00
)
[1] => Array
(
[name] => ''Samsung TV''
[price] => 425.00
)
[2] => Array
(
[name] => ''Sony TV''
[price] => 600.00
)
}
Como puede ver, no necesito preservar las claves de la matriz externa.
Puede usar usort()
:
function sort($a, $b) {
if ($a[''price''] == $b[''price'']) return 0;
return ($a[''price''] > $b[''price'']) ? 1 : -1;
}
usort($array, ''sort'');
Mejor aún si crea una clase como esta para reutilizar el código:
class FieldSorter {
public $field;
function __construct($field) {
$this->field = $field;
}
function cmp($a, $b) {
if ($a[$this->field] == $b[$this->field]) return 0;
return ($a[$this->field] > $b[$this->field]) ? 1 : -1;
}
}
$sorter = new FieldSorter(''price'');
usort($array, array($sorter, "cmp"));
De esta manera, puede ordenar fácilmente por otros campos.
Y aunque dijiste que las teclas de la matriz externa no tienen que ser preservadas, puedes lograr esto fácilmente usando uasort()
lugar de usort
.
Puede usar la función de usort con una devolución de llamada
Esta pregunta es un poco vieja, pero dejará la respuesta aquí para el futuro.
Desde la función php.net-Multisort , podemos usar el siguiente código;
$data= [[''volume'' => 67, ''edition'' => 2],[''volume'' => 85, ''edition'' => 6],...];
foreach ($data as $key => $row) {
$volume[$key] = $row[''volume''];
$edition[$key] = $row[''edition''];
}
array_multisort($volume, SORT_DESC, $edition, SORT_ASC, $data);
Lo anterior es para una clasificación estática de datos donde se cambian manualmente las columnas de clasificación.
Para un ejemplo más dinámico y robusto considere a continuación;
Supongamos que tengo los datos a continuación;
$data = [[1, ''Amanda'', ''Wright'', ''[email protected]'', ''Female'', ''135.114.57.89'', 31237],
[2, ''Theresa'', ''Larson'', ''[email protected]'', ''Female'', ''207.108.96.210'', 91011],
[3, ''Walter'', ''Kennedy'', ''[email protected]'', ''Male'', ''199.147.223.56'', 50114],
[4, ''Andrea'', ''Richards'', ''[email protected]'', ''Female'', ''230.195.124.95'', 76489],
[5, ''Carol'', ''Jones'', ''[email protected]'', ''Female'', ''250.197.111.90'', 56501],
[6, ''Alice'', ''Freeman'', ''[email protected]'', ''Female'', ''52.195.252.131'', 77170],
[7, ''Gerald'', ''Fisher'', ''[email protected]'', ''Male'', ''81.2.22.62'', 75625],....]
Si necesitamos ordenar los datos de la matriz anterior, podemos establecer los órdenes de clasificación en una matriz usando la sintaxis;
$qTable[$index]=$sort_order;
E.g. $qTable=[1=>''asc'',4=>''desc'',3=>''asc''];
Esto significa clasificar columna 1 ASC, columna 4 DESC y columna 3 ASC. Luego podemos usar la función siguiente para ordenar nuestros datos de base de datos multidimensionales;
function sortMulti($data, $orders)
{
$args = [];
foreach ($data as $key => $row) {
foreach ($orders as $index => $order) {
if (!isset($row[$index])) continue; //Ignore if column does''nt exist
$args[$index][''d''][$key] = $row[$index]; //Get all values within the column
$args[$index][''o''] = ''desc'' == strtolower($order) ? SORT_DESC : SORT_ASC; //Get the Sort order ''ASC'' is the default
}
}
$p = [];
//Below we need to organize our entries as arguments for array_multisort
foreach ($args as $arg) {
$p[] = $arg[''d''];
$p[] = $arg[''o''];
//Below we need to check if column contains only numeric or not.
//If all values are numeric, then we use numeric sort flag, otherwise NATURAL
//Manipulate for more conditions supported
$p[] = count($arg[''d'']) == count(array_filter($arg[''d''], ''is_numeric'')) ? SORT_NUMERIC : SORT_NATURAL;
}
$p[] = &$data; //Pass by reference
call_user_func_array(''array_multisort'', $p); //Call Php''s own multisort with parameters in required order.
return $data; //Our final array sorted.
}
Entonces podemos usarlo de la siguiente manera;
$data=[[...],[...],...];
$order=[1=>''asc'',4=>''desc'',3=>''asc''];
$sorted=sortMulti($data,$order);
Para los datos del conjunto de valores clave Eg $data=[[''c1''=>1212,''c2''=>''mynames''],...];
Use el orden como $order=[''c1''=>''desc'',''c10''=>''asc''];
Probé lo anterior con una matriz de 1000 registros. Espero que ayude a alguien.
Una alternativa al usort es crear una matriz que indexa la matriz que desea ordenar y está indexada por los datos que le gustaría ordenar.
En el siguiente fragmento, $ customAttributes es una matriz de objetos que me gustaría ordenar por nombre . Se crea First $ sort , se indexa por nombre y contiene el índice de matriz del elemento $ customAttributes correspondiente.
$sort = [];
foreach( $customAttributes as $c => $ca )
{
$sort[$ca->name] = $c;
}
ksort se usa para ordenar la matriz por clave.
ksort( $sort );
Una vez que se ha ordenado la matriz $ sort , repítala y cree la matriz $ ordered .
$ordered = [];
foreach( $sort as $s )
{
$ordered[] = $customAttributes[$s];
}
Me gusta esta solución porque hay menos llamadas a funciones que el uso de devoluciones de llamada.
Puede crear una función usted mismo como la siguiente
función privada orderArrayBycolumn ($ array, $ column) {
$newArray = [];
foreach ($array as $key => $value) {
$newArray[$value[$column]] = $value;
}
$array = [];
ksort($newArray);
foreach ($newArray as $key => $value) {
$array[] = $value;
}
return $array;
}