¿Es posible, en PHP, aplanar una matriz (bi / multi) dimensional sin usar recursividad o referencias?
Solo me interesan los valores para que las claves puedan ignorarse, estoy pensando en las líneas de array_map()
y array_values()
.
php
arrays
multidimensional-array
flatten
Alix Axel
fuente
fuente
Respuestas:
Puede usar la Biblioteca PHP estándar (SPL) para "ocultar" la recursividad.
huellas dactilares
fuente
iterator_to_array($it, false)
evita la necesidad del foreach.function flatten($arr){ $it = new RecursiveIteratorIterator(new RecursiveArrayIterator($arr)); return iterator_to_array($it, true); }
espero que esto ayude a otros.A partir de PHP 5.3, la solución más corta parece ser
array_walk_recursive()
con la nueva sintaxis de cierres:fuente
use
sintaxis para que funcione,array_walk_recursive
ya que no aceptará el$userdata
parámetro opcional por referenciaSolución para arreglo bidimensional
Por favor intente esto:
EDITAR: 21-ago-13
Aquí está la solución que funciona para una matriz multidimensional:
Ref: http://php.net/manual/en/function.call-user-func-array.php
fuente
call_user_func_array('array_merge', [])
(observe la matriz vacía) devuelve nulo y desencadena un error de advertencia de php. Es una solución ingeniosa si sabe con certeza que su matriz no estará vacía, pero esa no es una suposición común que muchos pueden hacer.$result = $array ?call_user_func_array('array_merge', $array) : [];
En PHP 5.6 y superior, puede aplanar matrices bidimensionales
array_merge
después de desempaquetar la matriz externa con el...
operador. El código es simple y claro.Esto también funciona con la colección de matrices asociativas.
Pero no funciona cuando la matriz externa tiene claves no numéricas. En ese caso,
array_values
primero deberá llamar .Actualización: Basado en el comentario de @MohamedGharib
Esto arrojará un error si la matriz externa está vacía, ya
array_merge
que se llamaría con cero argumentos. Se puede evitar agregando una matriz vacía como primer argumento.fuente
array_merge([], ...$a);
Para aplanar sin recursión (como ha pedido), puede usar una pila . Naturalmente, puede poner esto en una función propia
array_flatten
. La siguiente es una versión que funciona sin teclas :.Los elementos se procesan en su orden. Como los subelementos se moverán sobre la pila, se procesarán a continuación.
También es posible tener en cuenta las claves, sin embargo, necesitará una estrategia diferente para manejar la pila. Eso es necesario porque necesita lidiar con posibles claves duplicadas en los sub-arrays. Una respuesta similar en una pregunta relacionada: PHP Recorre la matriz multidimensional mientras conserva las claves
No estoy específicamente seguro, pero lo he probado en el pasado:
RecurisiveIterator
utiliza la recursividad, por lo que depende de lo que realmente necesita. También debería ser posible crear un iterador recursivo basado en pilas:Manifestación
No llegué hasta ahora, para implementar la pila en base a la
RecursiveIterator
cual creo que es una buena idea.fuente
if(!empty($value)){$flat[] = $value}
dentro de la instrucción else para evitar que se agregue vacío a la matriz de resultados. Función impresionante!Respuesta directa y de una sola línea .
Uso:
Salida (en PsySH):
Ahora depende de ti cómo manejarás las llaves. Salud
EDITAR (2017-03-01)
Citando la preocupación / problema de Nigel Alderton :
Citando la respuesta de Svish :
fuente
$array = ['a',['b','c']]
convierteArray ([0] => b, [1] => c )
. El'a'
se pierde porque'b'
también tiene una clave de0
.false
como segundo parámetro ($use_keys
) a laiterator_to_array
llamada.Utiliza la recursividad. Con suerte, al ver lo poco complejo que es, su miedo a la recurrencia se disipará una vez que vea lo poco complejo que es.
Salida:
fuente
Solo pensé en señalar que esto es un pliegue, por lo que se puede usar array_reduce:
EDITAR: Tenga en cuenta que esto se puede componer para aplanar cualquier número de niveles. Podemos hacer esto de varias maneras:
Por supuesto, también podríamos usar bucles, pero la pregunta pide una función de combinador a lo largo de las líneas de array_map o array_values.
fuente
fold
colocarla en 4 niveles, ofold . fold
obtener 3 niveles, ofold . fold . fold
obtener 2 niveles, etc. Esto también evita que los errores se oculten; p.ej. si quiero aplanar una matriz 5D pero me dan una matriz 4D, el error se activará de inmediato.$concat
, creo que deberías llamarlo$flatten
.array_merge
es el equivalente php de concat. Traté de serarray_concat
agregado como un alias paraarray_merge
.Aplana solo matrices bidimensionales:
fuente
Esta solución no es recursiva. Tenga en cuenta que el orden de los elementos será algo mixto.
fuente
shifting
el valor de la matriz y agregarlo nuevamente al final no tiene mucho sentido. Supongo que querías hacerlo en suarray_merge()
lugar?Creo que esta es la solución más limpia sin usar mutaciones ni clases desconocidas.
fuente
Pruebe la siguiente función simple:
Entonces de esto:
usted obtiene:
fuente
El truco es pasar las matrices de origen y de destino por referencia.
fuente
Fragmento de Gist
fuente
Puedes hacerlo con golosinas ouzo :
Ver: aquí
fuente
Si realmente no te gusta una recursión ... prueba a cambiar :)
Nota: en esta versión simple, esto no admite claves de matriz.
fuente
continue
, es algo más rápido.¿Qué tal usar un generador recursivo? https://ideone.com/d0TXCg
fuente
Para php 5.2
fuente
Esta versión puede hacer niveles profundos, superficiales o específicos:
fuente
Porque el código aquí parece aterrador. Aquí hay una función que también convertirá una matriz multidimensional en una sintaxis compatible con formularios html, pero que es más fácil de leer.
fuente
Esto se puede lograr usando
array_walk_recursive
Ejemplo de trabajo: - https://3v4l.org/FpIrG
fuente
Esta es mi solución, usando una referencia:
fuente
fuente
Aquí hay un enfoque simplista:
fuente
Cualquiera que busque una solución realmente limpia para esto; Aquí hay una opción:
Huellas dactilares
fuente
Solo publicando una solución más)
fuente
Si desea conservar también sus claves, esa es la solución.
Desafortunadamente, solo genera matrices anidadas finales, sin claves intermedias. Entonces para el siguiente ejemplo:
Salida es:
fuente
Necesitaba representar la matriz multidimensional de PHP en formato de entrada HTML.
fuente
$var['a']['b']['c'][0] = 'a'; ...
.Si tiene una matriz de objetos y desea aplanarla con un nodo, simplemente use esta función:
fuente