sumar multidimensional manejo elementos ejercicios dentro columna asociativo array agregar php sorting

multidimensional - manejo de array en php



¿Cómo ordenar una matriz de matrices asociativas por valor de una clave dada en PHP? (16)

Teniendo en cuenta esta matriz:

$inventory = array( array("type"=>"fruit", "price"=>3.50), array("type"=>"milk", "price"=>2.90), array("type"=>"pork", "price"=>5.43), );

Me gustaría ordenar los elementos de $inventory por precio para obtener:

$inventory = array( array("type"=>"pork", "price"=>5.43), array("type"=>"fruit", "price"=>3.50), array("type"=>"milk", "price"=>2.90), );

¿Cómo puedo hacer esto?


PHP 7+

A partir de PHP 7, esto se puede hacer de manera concisa usando usort con una función anónima que usa el operador de la nave espacial para comparar elementos.

Puedes hacer un tipo ascendente como este:

usort($inventory, function ($item1, $item2) { return $item1[''price''] <=> $item2[''price'']; });

O un tipo descendente como este:

usort($inventory, function ($item1, $item2) { return $item2[''price''] <=> $item1[''price'']; });

Para entender cómo funciona esto, tenga en cuenta que usort toma una función de comparación proporcionada por el usuario que debe comportarse de la siguiente manera (de la documentación):

La función de comparación debe devolver un número entero menor que, igual o mayor que cero si se considera que el primer argumento es respectivamente menor que, igual o mayor que el segundo.

Y tenga en cuenta también que <=> , el operador de la nave espacial,

devuelve 0 si ambos operandos son iguales, 1 si la izquierda es mayor y -1 si la derecha es mayor

que es exactamente lo que necesita usort . De hecho, casi toda la justificación dada para agregar <=> al idioma en https://wiki.php.net/rfc/combined-comparison-operator es que

facilita la escritura de devoluciones de llamada de pedido para su uso con usort()

PHP 5.3+

PHP 5.3 introdujo funciones anónimas, pero aún no tiene el operador de la nave espacial. Todavía podemos usar usort para ordenar nuestra matriz, pero es un poco más detallado y más difícil de entender:

usort($inventory, function ($item1, $item2) { if ($item1[''price''] == $item2[''price'']) return 0; return $item1[''price''] < $item2[''price''] ? -1 : 1; });

Tenga en cuenta que aunque es bastante común que los comparadores que tratan con valores enteros devuelvan la diferencia de los valores, como $item2[''price''] - $item1[''price''] , no podemos hacerlo de forma segura en este caso. Esto se debe a que los precios son números de punto flotante en el ejemplo del interrogador, pero la función de comparación que pasamos a usort tiene que devolver números enteros para que usort funcione correctamente:

La devolución de valores no enteros de la función de comparación, como float, dará como resultado una conversión interna a entero del valor de retorno de la devolución de llamada. Por lo tanto, valores como 0.99 y 0.1 se convertirán en un valor entero de 0, que comparará tales valores como iguales.

¡Esta es una trampa importante a tener en cuenta cuando se usa usort en PHP 5.x! Mi versión original de esta respuesta cometió este error y, sin embargo, acumulé diez votos por encima de miles de visitas aparentemente sin que nadie se diera cuenta del error grave. La facilidad con la que los despreocupados como yo pueden arruinar las funciones de comparación es precisamente la razón por la que el operador de nave espacial más fácil de usar se agregó al lenguaje en PHP 7.


Dado que los elementos de su matriz son matrices con claves de cadena, su mejor opción es definir una función de comparación personalizada. Es bastante rápido y fácil de hacer. Prueba esto:

function invenDescSort($item1,$item2) { if ($item1[''price''] == $item2[''price'']) return 0; return ($item1[''price''] < $item2[''price'']) ? 1 : -1; } usort($inventory,''invenDescSort''); print_r($inventory);

Produce lo siguiente:

Array ( [0] => Array ( [type] => pork [price] => 5.43 ) [1] => Array ( [type] => fruit [price] => 3.5 ) [2] => Array ( [type] => milk [price] => 2.9 ) )


Desde Ordenar una matriz de matrices asociativas por valor de clave dada en php :

uasort ( http://php.net/uasort ) le permite ordenar una matriz por su propia función definida. En tu caso, eso es simple:

$array = array( array(''price''=>''1000.50'',''product''=>''test1''), array(''price''=>''8800.50'',''product''=>''test2''), array(''price''=>''200.0'',''product''=>''test3'') ); function cmp($a, $b) { return $a[''price''] > $b[''price'']; } uasort($array, "cmp");


Esta función es reutilizable:

function usortarr(&$array, $key, $callback = ''strnatcasecmp'') { uasort($array, function($a, $b) use($key, $callback) { return call_user_func($callback, $a[$key], $b[$key]); }); }

Funciona bien en valores de cadena de forma predeterminada, pero tendrá que subponer la devolución de llamada para una función de comparación de números si todos sus valores son números.


Mientras que otros han sugerido correctamente el uso de array_multisort() , por alguna razón, ninguna respuesta parece reconocer la existencia de array_column() , lo que puede simplificar enormemente la solución. Así que mi sugerencia sería:

array_multisort(array_column($inventory, ''price''), SORT_DESC, $inventory);


Puede intentar definir su propia función de comparación y luego usar usort .


Puede usar usort con función anónima, por ejemplo

usort($inventory, function ($a, $b) { return strnatcmp($a[''price''], $b[''price'']); });


Terminé en esto:

function sort_array_of_array(&$array, $subfield) { $sortarray = array(); foreach ($array as $key => $row) { $sortarray[$key] = $row[$subfield]; } array_multisort($sortarray, SORT_ASC, $array); }

Simplemente llame a la función, pasando la matriz y el nombre del campo de la matriz de segundo nivel. Me gusta:

sort_array_of_array($inventory, ''price'');


Tienes razón, la función que estás buscando es array_multisort() .

Aquí hay un ejemplo tomado directamente del manual y adaptado a su caso:

$price = array(); foreach ($inventory as $key => $row) { $price[$key] = $row[''price'']; } array_multisort($price, SORT_DESC, $inventory);



Función dinámica completa Salté aquí para ordenar matrices asociativas y encontré esta función sorprendente en http://php.net/manual/en/function.sort.php . Esta función es muy dinámica y se clasifica en orden ascendente y descendente con una clave específica.

Función simple para ordenar una matriz por una clave específica. Mantiene asociación de índice

<?php function array_sort($array, $on, $order=SORT_ASC) { $new_array = array(); $sortable_array = array(); if (count($array) > 0) { foreach ($array as $k => $v) { if (is_array($v)) { foreach ($v as $k2 => $v2) { if ($k2 == $on) { $sortable_array[$k] = $v2; } } } else { $sortable_array[$k] = $v; } } switch ($order) { case SORT_ASC: asort($sortable_array); break; case SORT_DESC: arsort($sortable_array); break; } foreach ($sortable_array as $k => $v) { $new_array[$k] = $array[$k]; } } return $new_array; } $people = array( 12345 => array( ''id'' => 12345, ''first_name'' => ''Joe'', ''surname'' => ''Bloggs'', ''age'' => 23, ''sex'' => ''m'' ), 12346 => array( ''id'' => 12346, ''first_name'' => ''Adam'', ''surname'' => ''Smith'', ''age'' => 18, ''sex'' => ''m'' ), 12347 => array( ''id'' => 12347, ''first_name'' => ''Amy'', ''surname'' => ''Jones'', ''age'' => 21, ''sex'' => ''f'' ) ); print_r(array_sort($people, ''age'', SORT_DESC)); // Sort by oldest first print_r(array_sort($people, ''surname'', SORT_ASC)); // Sort by surname


Se probó en 100 000 registros: tiempo en segundos (calculado por función de microtiempo). Solo para valores únicos en posiciones claves de clasificación.

Solución de función de @Josh Davis: Tiempo empleado: 1.5768740177155

Solución de la mina: Tiempo empleado: 0.094044923782349

Solución:

function SortByKeyValue($data, $sortKey, $sort_flags=SORT_ASC) { if (empty($data) or empty($sortKey)) return $data; $ordered = array(); foreach ($data as $key => $value) $ordered[$value[$sortKey]] = $value; ksort($ordered, $sort_flags); return array_values($ordered); *// array_values() added for identical result with multisort* }


<?php $inventory = array( array("type"=>"fruit", "price"=>3.50), array("type"=>"milk", "price"=>2.90), array("type"=>"pork", "price"=>5.43), ); function myfunc($a,$b){ return strnatcmp($a[''price''],$b[''price'']); } $result=usort ($inventory,"myfunc");?> <pre><?php print_r(array_reverse($inventory)); ?></pre>

La solución simple :)

la salida es,

Array ( [0] => Array ( [type] => pork [price] => 5.43 ) [1] => Array ( [type] => fruit [price] => 3.5 ) [2] => Array ( [type] => milk [price] => 2.9 ) )


$arr1 = array( array(''id''=>1,''name''=>''aA'',''cat''=>''cc''), array(''id''=>2,''name''=>''aa'',''cat''=>''dd''), array(''id''=>3,''name''=>''bb'',''cat''=>''cc''), array(''id''=>4,''name''=>''bb'',''cat''=>''dd'') ); $result1 = array_msort($arr1, array(''name''=>SORT_DESC); $result2 = array_msort($arr1, array(''cat''=>SORT_ASC); $result3 = array_msort($arr1, array(''name''=>SORT_DESC, ''cat''=>SORT_ASC)); function array_msort($array, $cols) { $colarr = array(); foreach ($cols as $col => $order) { $colarr[$col] = array(); foreach ($array as $k => $row) { $colarr[$col][''_''.$k] = strtolower($row[$col]); } } $eval = ''array_multisort(''; foreach ($cols as $col => $order) { $eval .= ''$colarr[/'''.$col.''/'],''.$order.'',''; } $eval = substr($eval,0,-1).'');''; eval($eval); $ret = array(); foreach ($colarr as $col => $arr) { foreach ($arr as $k => $v) { $k = substr($k,1); if (!isset($ret[$k])) $ret[$k] = $array[$k]; $ret[$k][$col] = $array[$k][$col]; } } return $ret; }


$inventory = array(array("type"=>"fruit", "price"=>3.50), array("type"=>"milk", "price"=>2.90), array("type"=>"pork", "price"=>5.43), ); function pricesort($a, $b) { $a = $a[''price'']; $b = $b[''price'']; if ($a == $b) return 0; return ($a > $b) ? -1 : 1; } usort($inventory, "pricesort"); // uksort($inventory, "pricesort"); print("first: ".$inventory[0][''type'']."/n/n"); // for usort(): prints milk (item with lowest price) // for uksort(): prints fruit (item with key 0 in the original $inventory) // foreach prints the same for usort and uksort. foreach($inventory as $i){ print($i[''type''].": ".$i[''price'']."/n"); }

salidas:

first: pork pork: 5.43 fruit: 3.5 milk: 2.9


//Just in one line custom function function cmp($a, $b) { return (float) $a[''price''] < (float)$b[''price'']; } @uasort($inventory, "cmp"); print_r($inventory); //result Array ( [2] => Array ( [type] => pork [price] => 5.43 ) [0] => Array ( [type] => fruit [price] => 3.5 ) [1] => Array ( [type] => milk [price] => 2.9 ) )