Trabajando Con Arreglos PHP de la Manera Correcta
Spanish (Español) translation by Rafael Chavarría (you can also view the original English article)
En este tutorial, voy a hacer una lista de funciones de arreglo PHP comunes con ejemplos de uso y mejores prácticas. Cada desarrollador PHP debe saber cómo usarlas y cómo combinar funciones de arreglo para hacer el código legible y corto.
También, hay una presentación con ejemplos de código dados, así que puedes descargarla de los enlaces relacionados y mostrarla a tus colegas para construir un equipo más fuerte.
Los Básicos
Comencemos con las funciones básicas que trabajan con llaves de arreglos y valores. Una de ellas es array_combine(), que crea un arreglo usando un arreglo para llaves y otro para sus valores:
1 |
$keys = ['sky', 'grass', 'orange']; |
2 |
$values = ['blue', 'green', 'orange']; |
3 |
|
4 |
$array = array_combine($keys, $values); |
5 |
print_r($array); |
6 |
|
7 |
// Array
|
8 |
// (
|
9 |
// [sky] => blue
|
10 |
// [grass] => green
|
11 |
// [orange] => orange
|
12 |
// )
|
Deberías saber, que la función array_values() devuelve un arreglo indizado de valores, array_keys() devuelve un arreglo de llaves de un arreglo dado, y array_flip() intercambia las llaves con valores:
1 |
print_r(array_keys($array)); // ['sky', 'grass', 'orange'] |
2 |
print_r(array_values($array)); // ['blue', 'green', 'orange'] |
3 |
print_r(array_flip($array)); |
4 |
|
5 |
// Array
|
6 |
// (
|
7 |
// [blue] => sky
|
8 |
// [green] => grass
|
9 |
// [orange] => orange
|
10 |
// )
|
Haz Tu Código Más Corto
La función list(), que no es realmente una función, sino una construcción de lenguaje, está diseñada para asignar variables de una manera corta. Por ejemplo, aquí está un ejemplo básico de usar la función list():
1 |
// define array
|
2 |
$array = ['a', 'b', 'c']; |
3 |
|
4 |
// without list()
|
5 |
$a = $array[0]; |
6 |
$b = $array[1]; |
7 |
$c = $array[2]; |
8 |
|
9 |
// with list()
|
10 |
list($a, $b, $c) = $array; |
Esta construcción funciones perfectamente con funciones como preg_slit() o explode(). También, puedes omitir algunos parámetros, si no necesitas que estén definidos:
1 |
$string = 'hello|wild|world'; |
2 |
list($hello, , $world) = explode('|', $string); |
3 |
echo("$hello, $world"); // hello, world |
También, list() puede ser usado con foreach, que hace a esta construcción mucho mejor:
1 |
$arrays = [[1, 2], [3, 4], [5, 6]]; |
2 |
|
3 |
foreach ($arrays as list($a, $b)) { |
4 |
$c = $a + $b; |
5 |
echo($c . ', '); // 3, 7, 11, |
6 |
}
|
Con la función extract(), puedes exportar un arreglo asociativo a variables. Por cada elemento de un arreglo, una variable será creada con el nombre de una llave y valor como un valor del elemento:
1 |
$array = [ |
2 |
'clothes' => 't-shirt', |
3 |
'size' => 'medium', |
4 |
'color' => 'blue', |
5 |
];
|
6 |
|
7 |
extract($array); |
8 |
|
9 |
echo("$clothes $size $color"); // t-shirt medium blue |
Ten en cuenta que extract() no es seguro si estás trabajando con datos de usuario (como resultados o peticiones), así que es mejor usar esta función con las banderas EXTR_IF_EXISTS y EXTR_PREFIX_ALL.
El opuesto de la función anterior es la función compact(), que hace un arreglo asociativo de variables:
1 |
$clothes = 't-shirt'; |
2 |
$size = 'medium'; |
3 |
$color = 'blue'; |
4 |
|
5 |
$array = compact('clothes', 'size', 'color'); |
6 |
print_r($array); |
7 |
|
8 |
// Array
|
9 |
// (
|
10 |
// [clothes] => t-shirt
|
11 |
// [size] => medium
|
12 |
// [color] => blue
|
13 |
// )
|
Filtrando Funciones
Hay una gran función para filtrado de arreglo, y se llama array_filter(). Pasa el arreglo como el primer parámetro y una función anónima como el segundo parámetro. Devuelve true en una función callback si quieres dejar este elemento en el arreglo, y false si no quieres:
1 |
$numbers = [20, -3, 50, -99, 55]; |
2 |
|
3 |
$positive = array_filter($numbers, function($number) { |
4 |
return $number > 0; |
5 |
});
|
6 |
|
7 |
print_r($positive); // [0 => 20, 2 => 50, 4 => 55] |
Hay una manera de filtrar no solo por los valores. Puedes usar ARRAY_FILTER_USE_KEY o ARRAY_FILTER_USE_BOTH como un tercer parámetro para pasar la llave o el valor y la llave a la función callback.
También, puedes llamar a array_filter() sin un callback para remover todos los valores vacíos:
1 |
$numbers = [-1, 0, 1]; |
2 |
|
3 |
$not_empty = array_filter($numbers); |
4 |
|
5 |
print_r($not_empty); // [0 => -1, 2 => 1] |
Puedes obtener solo valores únicos de un arreglo usando la función array_unique(). Nota que la función conservará las llaves de los primeros elementos únicos:
1 |
$array = [1, 1, 1, 1, 2, 2, 2, 3, 4, 5, 5]; |
2 |
$uniques = array_unique($array); |
3 |
|
4 |
print_r($uniques); |
5 |
|
6 |
// Array
|
7 |
// (
|
8 |
// [0] => 1
|
9 |
// [4] => 2
|
10 |
// [7] => 3
|
11 |
// [8] => 4
|
12 |
// [9] => 5
|
13 |
// )
|
Con array_column(), puedes obtener una lista de valores de columna de un arreglo multi-dimensional, como una respuesta de una base de datos SQL o una importación desde un archivo CSV. Solo pasa un arreglo y nombre de columna:
1 |
$array = [ |
2 |
['id' => 1, 'title' => 'tree'], |
3 |
['id' => 2, 'title' => 'sun'], |
4 |
['id' => 3, 'title' => 'cloud'], |
5 |
];
|
6 |
|
7 |
$ids = array_column($array, 'id'); |
8 |
|
9 |
print_r($ids); // [1, 2, 3] |
Comenzando desde PHP 7, array_column() se vuelve incluso más poderoso, porque ahora se permite trabajar con un arreglo de objetos. Así que trabajar con un arreglo de modelos se volvió más sencillo.
1 |
$cinemas = Cinema::find()->all(); |
2 |
$cinema_ids = array_column($cinemas, 'id'); // php7 forever! |
Recorriendo los Arreglos
Usando array_map(), puedes aplicar un callback a cada elemento de un arreglo. Puedes pasar un nombre de función o función anónima para obtener un nuevo arreglo basado en el arreglo dado:
1 |
$cities = ['Berlin', 'KYIV', 'Amsterdam', 'Riga']; |
2 |
$aliases = array_map('strtolower', $cities); |
3 |
|
4 |
print_r($aliases); // ['berlin', 'kyiv, 'warsaw', 'riga'] |
5 |
|
6 |
$numbers = [1, -2, 3, -4, 5]; |
7 |
$squares = array_map(function($number) { |
8 |
return $number ** 2; |
9 |
}, $numbers); |
10 |
|
11 |
print_r($squares); // [1, 4, 9, 16, 25] |
Hay un mito sobre que no hay manera de pasar valores y llaves de un arreglo a un callback, pero podemos desmitificarlo:
1 |
$model = ['id' => 7, 'name'=>'James']; |
2 |
|
3 |
$callback = function($key, $value) { |
4 |
return "$key is $value"; |
5 |
};
|
6 |
|
7 |
$res = array_map($callback, array_keys($model), $model); |
8 |
print_r($res); |
9 |
|
10 |
// Array
|
11 |
// (
|
12 |
// [0] => id is 7
|
13 |
// [1] => name is James
|
14 |
// )
|
Pero esto se ve sucio. Es mejor usar array_walk() en su lugar. Esta función luce igual que array_map(), pero funciona diferente. Primero que todo, un arreglo es pasado por una referencia, así que array_walk() no crea un nuevo arreglo, pero cambia un arreglo dado. Así que como un arreglo fuente, puedes pasar el valor del arreglo por una referencia en un callback. Las llaves de arreglo también pueden ser pasadas fácilmente:
1 |
$fruits = [ |
2 |
'banana' => 'yellow', |
3 |
'apple' => 'green', |
4 |
'orange' => 'orange', |
5 |
];
|
6 |
|
7 |
array_walk($fruits, function(&$value, $key) { |
8 |
$value = "$key is $value"; |
9 |
});
|
10 |
|
11 |
print_r($fruits); |
12 |
|
13 |
// Array
|
14 |
// (
|
15 |
// [banana] => banana is yellow
|
16 |
// [apple] => apple is green
|
17 |
// [orange] => orange is orange
|
18 |
// )
|
Uniendo los Arreglos
La mejor manera de unir dos o más arreglos en PHP es usar la función array_merge(). Los elementos de arreglos pueden ser combinados, y los valores con las mismas llaves de cadena serán sobrescritos con el último valor:
1 |
$array1 = ['a' => 'a', 'b' => 'b', 'c' => 'c']; |
2 |
$array2 = ['a' => 'A', 'b' => 'B', 'D' => 'D']; |
3 |
|
4 |
$merge = array_merge($array1, $array2); |
5 |
print_r($merge); |
6 |
// Array
|
7 |
// (
|
8 |
// [a] => A
|
9 |
// [b] => B
|
10 |
// [c] => c
|
11 |
// [D] => D
|
12 |
// )
|
Para remover valores de arreglos de otro arreglo (o arreglos), usa array_diff(). PAra obtener valores que están presentes en arreglos dados, usa array_intersect(). Los siguientes ejemplos mostrarán cómo funciona:
1 |
$array1 = [1, 2, 3, 4]; |
2 |
$array2 = [3, 4, 5, 6]; |
3 |
|
4 |
$diff = array_diff($array1, $array2); |
5 |
print_r($diff); // [0 => 1, 1 => 2] |
6 |
|
7 |
$intersect = array_intersect($array1, $array2); |
8 |
print_r($intersect); // [2 => 3, 3 => 4] |
Haz las Cuentas Con Valores de Arreglos
Usa array_sum() para obtener una suma de valores de arreglo, array_product() para multiplicarlos, o crea tu propia fórmula con array_reduce():
1 |
$numbers = [1, 2, 3, 4, 5]; |
2 |
|
3 |
echo(array_sum($numbers)); // 15 |
4 |
echo(array_product($numbers)); // 120 |
5 |
|
6 |
echo(array_reduce($numbers, function($carry, $item) { |
7 |
return $carry ? $carry / $item : 1; |
8 |
})); // 0.0083 = 1/2/3/4/5 |
Para contar todos los valores de un arreglo, usa array_count_values(). Dará valores únicos de un arreglo dado como llaves y una cuentas de estos valores como un valor:
1 |
$things = ['apple', 'apple', 'banana', 'tree', 'tree', 'tree']; |
2 |
$values = array_count_values($things); |
3 |
|
4 |
print_r($values); |
5 |
|
6 |
// Array
|
7 |
// (
|
8 |
// [apple] => 2
|
9 |
// [banana] => 1
|
10 |
// [tree] => 3
|
11 |
// )
|
Generando Arreglos
Para generar un arreglo con un tamaño dado y el mismo valor, usa array_fill():
1 |
$bind = array_fill(0, 5, '?'); |
2 |
print_r($bind); // ['?', '?', '?', '?', '?'] |
Para generar un arreglo con un rango de llaves y valores, como horas del día o letras, usa range():
1 |
$letters = range('a', 'z'); |
2 |
print_r($letters); // ['a', 'b', ..., 'z'] |
3 |
|
4 |
$hours = range(0, 23); |
5 |
print_r($hours); // [0, 1, 2, ..., 23] |
Para obtener una parte de un arreglo---por ejemplo, solo los tres primeros elementos---usa array_slice():
1 |
$numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; |
2 |
$top = array_slice($numbers, 0, 3); |
3 |
print_r($top); // [1, 2, 3] |
Ordenando Arreglos
Es bueno recordar que cada función de ordenamiento en PHP funciona con arreglos por una referencia y devuelve true en éxito o false en fracaso. Hay una función básica de ordenamiento llamada sort(), y esta ordena valores en orden ascendente sin conservar llaves. La función de ordenamiento puede ser prepuesta por las siguientes letras:
- a, acomoda conservando llaves
- k, acomoda por llaves
- r, acomoda en orden inverso/descendiente
- u, acomoda con una función de usuario
Puedes ver las combinaciones de estas letras en la siguiente tabla:
| a | k | r | u | |
| a | asort | arsort | uasort | |
| k | ksort | krsort | ||
| r | arsort | krsort | rsort | |
| u | uasort | usort |
Combinando Funciones de Arreglo Como un Jefe
La magia verdadera comienza cuando empiezas a combinar funciones de arreglos. Aquí está cómo puedes cortar y remover valores vacíos en solo una línea de código con array_filter() y array_map():
1 |
$values = ['say ', ' bye', ' ', ' to', ' spaces ', ' ']; |
2 |
|
3 |
$words = array_filter(array_map('trim', $values)); |
4 |
print_r($words); // ['say', 'bye', 'to', 'spaces'] |
Para crear un id para un pequeño mapa de título desde un arreglo de modelos, podemos usar una combinación de array_combine() y array_column():
1 |
$models = [$model1, $model2, $model3]; |
2 |
|
3 |
$id_to_title = array_combine( |
4 |
array_column($models, 'id'), |
5 |
array_column($models, 'title') |
6 |
);
|
Para obtener los tres valores superiores de un arreglo, podemos usar array_count_values(), arsort(), y array_slice():
1 |
$letters = ['a', 'a', 'a', 'a', 'b', 'b', 'c', 'd', 'd', 'd', 'd', 'd']; |
2 |
|
3 |
$values = array_count_values($letters); // get key to count array |
4 |
arsort($values); // sort descending preserving key |
5 |
$top = array_slice($values, 0, 3); // get top 3 |
6 |
|
7 |
print_r($top); |
8 |
// Array
|
9 |
// (
|
10 |
// [d] => 5
|
11 |
// [a] => 4
|
12 |
// [b] => 2
|
13 |
// )
|
Es sencillo usar array_sum() y array_map() para calcular la suma de orden en unas cuantas filas:
1 |
$order = [ |
2 |
['product_id' => 1, 'price' => 99, 'count' => 1], |
3 |
['product_id' => 2, 'price' => 50, 'count' => 2], |
4 |
['product_id' => 2, 'price' => 17, 'count' => 3], |
5 |
];
|
6 |
|
7 |
$sum = array_sum(array_map(function($product_row) { |
8 |
return $product_row['price'] * $product_row['count']; |
9 |
}, $order)); |
10 |
|
11 |
print_r($sum); // 250 |
Conclusión
Como puedes ver, el conocimiento de las principales funciones de arreglos puede hacer tu código mucho más corto y más legible. Por supuesto, PHP tiene muchas más funciones de arreglos, e incluso las funciones dadas tienen muchas variaciones para usar con parámetros y banderas extras, pero creo que en este tutorial hemos cubierto los básicos que todo desarrollador PHP debería saber.
Por favor nota que he creado una presentación con los ejemplos dados, para que puedas descargarla de los enlaces relacionados y mostrarla a tu equipo.
Si tienes cualquier pregunta, no dudes en hacerla en los comentarios del artículo.



