Alex
¿Es posible en PHP hacer algo como esto? ¿Cómo harías para escribir una función? Aquí hay un ejemplo. El orden es lo más importante.
$customer['address'] = '123 fake st';
$customer['name'] = 'Tim';
$customer['dob'] = '12/08/1986';
$customer['dontSortMe'] = 'this value doesnt need to be sorted';
Y me gustaría hacer algo como
$properOrderedArray = sortArrayByArray($customer, array('name', 'dob', 'address'));
Porque al final uso un foreach() y no están en el orden correcto (porque agrego los valores a una cadena que debe estar en el orden correcto y no sé de antemano todas las claves de matriz/ valores).
Revisé las funciones de matriz interna de PHP, pero parece que solo puede ordenar alfabéticamente o numéricamente.
vals oscuro4
Solo usa array_merge
o array_replace
. array_merge
funciona comenzando con la matriz que le das (en el orden correcto) y sobrescribiendo/agregando las claves con datos de tu matriz real:
$customer['address'] = '123 fake st';
$customer['name'] = 'Tim';
$customer['dob'] = '12/08/1986';
$customer['dontSortMe'] = 'this value doesnt need to be sorted';
$properOrderedArray = array_merge(array_flip(array('name', 'dob', 'address')), $customer);
// or
$properOrderedArray = array_replace(array_flip(array('name', 'dob', 'address')), $customer);
// $properOrderedArray: array(
// 'name' => 'Tim',
// 'dob' => '12/08/1986',
// 'address' => '123 fake st',
// 'dontSortMe' => 'this value doesnt need to be sorted')
PD: estoy respondiendo a esta pregunta “obsoleta”, porque creo que todos los bucles dados como respuestas anteriores son excesivos.
-
Funciona bien si tiene teclas de cadena pero no para la numérica. PHP Docs: “Si las matrices de entrada tienen las mismas claves de cadena, el valor posterior de esa clave sobrescribirá la anterior. Sin embargo, si las matrices contienen claves numéricas, el valor posterior no sobrescribirá el valor original, pero será adjunto”.
– bolbol
7 de noviembre de 2012 a las 6:52
-
Bien, pero ¿y si las claves no existen en los valores? Necesito esto, pero solo si existe alguna de las claves… Probablemente necesite un foreach entonces…
– Salomón Closson
8 mayo 2014 a las 22:49
-
para mi caso, es array_replace en lugar de array_merge. array_merge combina ambos valores en lugar de reemplazar la segunda matriz en las claves ordenadas.
– neofreko
12 de noviembre de 2014 a las 6:26
-
Me topé con su solución hace un par de años mientras buscaba algo diferente, y pensé, esto es extremadamente eficiente en comparación con los bucles. ¡Ahora necesito su solución y me llevó una hora de búsqueda volver a encontrarla! ¡Gracias!
– Miguel
13 de noviembre de 2017 a las 3:29
-
Además, si la matriz ‘order’ (es decir, array(‘name’, ‘dob’, ‘address’)) tiene más claves que la matriz para ordenar, entonces array_intersect adicional de la matriz ordenada resultante con la matriz original se cortaría claves perdidas que se agregaron en array_merge.
– bb
8 de enero de 2018 a las 10:24
Eran Galperín
Ahí tienes:
function sortArrayByArray(array $array, array $orderArray) {
$ordered = array();
foreach ($orderArray as $key) {
if (array_key_exists($key, $array)) {
$ordered[$key] = $array[$key];
unset($array[$key]);
}
}
return $ordered + $array;
}
-
Entonces, ¿puedes unir 2 matrices con un signo +? Nunca supe eso, he estado usando
array_merge()
!– Alex
24 de septiembre de 2009 a las 23:08
-
¿Es esto mejor que usar
usort()
ouasort()
?– parques de subvenciones
25 de septiembre de 2009 a las 19:57
-
Debes insertar un
break
declaración una vez que se ha encontrado el valor.– Adel
26 de septiembre de 2011 a las 14:50
-
@alex Tenga mucho cuidado cuando reemplace
array_merge()
con la matriz+
operador. Fusiona por clave (también para claves numéricas) y desde de izquierda a derechamientrasarray_merge
se fusiona desde De derecha a izquierda y nunca sobrescribe las teclas numéricas. P.ej[0,1,2]+[0,5,6,7] = [0,1,2,7]
mientrasarray_merge([0,1,2],[0,5,6,7]) = [0,1,2,0,5,6,7]
y['a' => 5] + ['a' => 7] = ['a' => 5]
peroarray_merge(['a' => 5], ['a' => 7]) = ['a' => 7]
.– gripe
5 de agosto de 2015 a las 8:07
-
El
+
o operador de unión es perfectamente válido de acuerdo con Documentación PHP en algunos casos de uso, es exactamente lo que desea si tiene que mantener las teclas numéricas.– Hexodus
12 mayo 2017 a las 21:14
Que tal esta solucion
$order = array(1,5,2,4,3,6);
$array = array(
1 => 'one',
2 => 'two',
3 => 'three',
4 => 'four',
5 => 'five',
6 => 'six'
);
uksort($array, function($key1, $key2) use ($order) {
return (array_search($key1, $order) > array_search($key2, $order));
});
-
Esto no es muy eficiente. Para cada comparación, se realizan dos búsquedas lineales en la matriz. Si asumimos que la complejidad temporal de uksort() es
O(n * log n)
entonces este algoritmo se ejecuta enO(n^2 * log(n))
.– El operador
23 de enero de 2020 a las 9:12
-
Estas soluciones funcionan bastante bien para las matrices a las que les falta un valor en el orden de clasificación. Para arreglos pequeños, la complejidad es probablemente insignificante. Las soluciones con múltiples funciones de matriz podrían ser incluso peores.
– 2.º kauboy
27 de julio de 2021 a las 15:56
-
justo
array_flip
el $pedido antesuse
y va más rápido– V.Volkov
6 de agosto de 2022 a las 6:59
-
@V.Volkov Pero en ese caso obtendrá un resultado incorrecto
-Peter de Groot
7 de agosto de 2022 a las 7:13
-
@PeterdeGroot lo siento por no aclarar 🙂
$order = array_flip( $order );
antes deuksort
yreturn $order[ $key1 ] > $order[ $key2 ];
adentrouksort
– V.Volkov
7 de agosto de 2022 a las 7:47
Otra forma para PHP >= 5.3.0:
$customer['address'] = '123 fake st';
$customer['name'] = 'Tim';
$customer['dob'] = '12/08/1986';
$customer['dontSortMe'] = 'this value doesnt need to be sorted';
$customerSorted = array_replace(array_flip(array('name', 'dob', 'address')), $customer);
Resultado:
Array (
[name] => Tim
[dob] => 12/08/1986
[address] => 123 fake st
[dontSortMe] => this value doesnt need to be sorted
)
Funciona bien con cadenas y teclas numéricas.
function sortArrayByArray(array $toSort, array $sortByValuesAsKeys)
{
$commonKeysInOrder = array_intersect_key(array_flip($sortByValuesAsKeys), $toSort);
$commonKeysWithValue = array_intersect_key($toSort, $commonKeysInOrder);
$sorted = array_merge($commonKeysInOrder, $commonKeysWithValue);
return $sorted;
}
Stephan Vierkant
Usé la solución de Darkwaltz4 pero usé array_fill_keys
en lugar de array_flip
para llenar con NULL
si una clave no está configurada $array
.
$properOrderedArray = array_replace(array_fill_keys($keys, null), $array);
hakré
Tome una matriz como su orden:
$order = array('north', 'east', 'south', 'west');
Puede ordenar otra matriz según los valores usando array_intersect
Documentos:
/* sort by value: */
$array = array('south', 'west', 'north');
$sorted = array_intersect($order, $array);
print_r($sorted);
O en su caso, para ordenar por claves, utilice array_intersect_key
Documentos:
/* sort by key: */
$array = array_flip($array);
$sorted = array_intersect_key(array_flip($order), $array);
print_r($sorted);
Ambas funciones mantendrán el orden del primer parámetro y solo devolverán los valores (o claves) del segundo arreglo.
Entonces, para estos dos casos estándar, no necesita escribir una función por su cuenta para realizar la clasificación/reorganización.
-
La intersección se desharía de aquellas entradas que no conoce de antemano.
– DanMan
6 de marzo de 2013 a las 15:02
-
Esto es incorrecto para ordenar por claves. array_intersect_key solo devolverá los valores de array1, no de array2
– escalofriante
21 de enero de 2015 a las 14:30
-
De acuerdo con pavsid: el ejemplo array_intersect_key es incorrecto: devuelve los valores de la primera matriz, no de la segunda.
–Jonathan Aquino
15 de abril de 2015 a las 3:18