En esta lección se comentan varias funciones útiles para trabajar con matrices. La información general sobre matrices en PHP se encuentra en la lección Matrices.
Un detalle a tener en cuenta al utilizar cualquiera de las funciones de matrices disponibles en PHP es si la función devuelve una matriz con el resultado de la operación o si la función transforma la matriz enviada como argumento de la función:
<?php
$matriz = [ ... ];
$resultado = funcion_de_matrices($matriz);
// El resto del programa puede acceder tanto a la matriz inicial $matriz
// como al resultado de la función (que puede ser una matriz o un valor escalar).
?>
<?php
$matriz = [ ... ];
$matriz = funcion_de_matrices($matriz);
// El resto del programa ya no puede acceder a los valores que había en la matriz inicial,
// solamente puede acceder al resultado de la función (que puede ser una matriz o un valor escalar).
?>
<?php
$matriz = [ ... ];
$resultado = $matriz;
funcion_de_matrices($resultado);
// El resto del programa puede acceder tanto a la matriz inicial $matriz
// como al resultado de la función (que en estos casos suele ser siempre una matriz).
?>
<?php
$matriz = [ ... ];
funcion_de_matrices($matriz);
// El resto del programa ya no puede acceder a los valores que había en la matriz inicial,
// solamente puede acceder al resultado de la función (que en estos casos suele ser siempre una matriz).
?>
La función range($inicio, $final, $paso) genera una matriz de valores en sucesión aritmética, es decir los valores desde $inicio hasta $final contando de $paso en $paso (sin superar el valor $final).
Nota: A diferencia del tipo range() de Python, el valor $final de la sucesión se incluye en su caso en el resultado.
<?php
$valores = range(1, 10, 3);
print "<pre>\n"; print_r($valores); print "</pre>\n";
?>
Array ( [0] => 1 [1] => 4 [2] => 7 [3] => 10 )
<?php
$valores = range(0.5, 1.5, 0.4);
print "<pre>\n"; print_r($valores); print "</pre>\n";
?>
Array ( [0] => 0.5 [1] => 0.9 [2] => 1.3 )
La función array_merge($matriz_1, $matriz_2, ...) mezcla dos o más matrices en una única matriz.
Si los índices son numéricos, al mezclar las matrices se conservan todos los valores y se renumeran los índices.
<?php
$uno = [1, 2, 4];
$dos = [1, 3, 9];
$final = array_merge($uno, $dos);
print "<pre>\n"; print_r($final); print "</pre>\n";
?>
Array ( [0] => 1 [1] => 2 [2] => 4 [3] => 1 [4] => 3 [5] => 9 )
<?php
$uno = [1 => 1, 2 => 2, 3 => 4];
$dos = [2 => 1, 3 => 3, 4 => 9];
$final = array_merge($uno, $dos);
print "<pre>\n"; print_r($final); print "</pre>\n";
?>
Array ( [0] => 1 [1] => 2 [2] => 4 [3] => 1 [4] => 3 [5] => 9 )
Si los índices no son numéricos y hay índices que coinciden, al mezclar las matrices los valores se sobrescriben.
<?php
$uno = ["a" => 1, "b" => 2, "c" => 4];
$dos = ["b" => 10, "c" => 20, "d" => 40];
$final = array_merge($uno, $dos);
print "<pre>\n"; print_r($final); print "</pre>\n";
?>
Array ( [a] => 1 [b] => 10 [c] => 20 [d] => 40 )
Si hay índices numéricos e índices no numéricos y hay índices que coinciden, al mezclar las matrices los valores de índices numéricos se conservan (aunque se renumeren los índices), pero los no numéricos se sobrescriben.
<?php
$uno = [2 => 1, "b" => 2, "c" => 4];
$dos = [2 => 100, "c" => 40, "d" => 60];
$final = array_merge($uno, $dos);
print "<pre>\n"; print_r($final); print "</pre>\n";
?>
Array ( [0] => 1 [b] => 2 [c] => 40 [1] => 100 [d] => 60 )
Por la manera en que realiza la mezcla de matrices, el orden de las matrices al llamar a la función afecta al resultado.
<?php
$uno = [1 => 10, "a" => 20];
$dos = [1 => 30, "b" => 40];
$final = array_merge($uno, $dos);
print "<pre>\n"; print_r($final); print "</pre>\n";
$final = array_merge($dos, $uno);
print "<pre>\n"; print_r($final); print "</pre>\n";
?>
Array ( [0] => 10 [a] => 20 [1] => 30 [b] => 40 ) Array ( [0] => 30 [a] => 40 [1] => 10 [b] => 20 )
<?php
$uno = [1 => 10, "a" => 20];
$dos = [1 => 30, "a" => 40];
$final = array_merge($uno, $dos);
print "<pre>\n"; print_r($final); print "</pre>\n";
$final = array_merge($dos, $uno);
print "<pre>\n"; print_r($final); print "</pre>\n";
?>
Array ( [0] => 10 [a] => 40 [1] => 30 ) Array ( [0] => 30 [a] => 20 [1] => 10 )
La función count($matriz) permite contar los elementos de una matriz.
<?php
$nombres[1] = "Ana";
$nombres[10] = "Bernardo";
$nombres[25] = "Carmen";
$elementos = count($nombres);
print "<p>La matriz tiene $elementos elementos.</p>\n";
print "\n";
print "<pre>\n"; print_r($nombres); print "</pre>\n";
?>
La matriz tiene 3 elementos.
Array ( [1] => Ana [10] => Bernardo [25] => Carmen )
En una matriz multidimensional, la función count($matriz) considera la matriz como un vector de vectores y devuelve simplemente el número de elementos del primer índice:
<?php
$datos["pepe"]["edad"] = 25;
$datos["pepe"]["peso"] = 80;
$datos["juan"]["edad"] = 22;
$datos["juan"]["peso"] = 75;
$datos["ana"]["edad"] = 30;
$elementos = count($datos);
print "<p>La matriz tiene $elementos elementos.</p>\n";
print "\n";
print "<pre>\n"; print_r($datos); print "</pre>\n";
?>
La matriz tiene 3 elementos.
Array ( [pepe] => Array ( [edad] => 25 [peso] => 80 ) [juan] => Array ( [edad] => 22 [peso] => 75 ) [ana] => Array ( [edad] => 30 ) )
Para contar todos los elementos de una matriz multidimensional, se puede utilizar la función count($matriz, COUNT_RECURSIVE).
<?php
$datos["pepe"]["edad"] = 25;
$datos["pepe"]["peso"] = 80;
$datos["juan"]["edad"] = 22;
$datos["juan"]["peso"] = 75;
$datos["ana"]["edad"] = 30;
$elementos = count($datos, COUNT_RECURSIVE);
print "<p>La matriz tiene $elementos elementos.</p>\n";
print "\n";
print "<pre>\n"; print_r($datos); print "</pre>\n";
?>
La matriz tiene 8 elementos.
Array ( [pepe] => Array ( [edad] => 25 [peso] => 80 ) [juan] => Array ( [edad] => 22 [peso] => 75 ) [ana] => Array ( [edad] => 30 ) )
En el ejemplo anterior, la respuesta 8 se debe a que la función count()recursiva considera la matriz como un vector de vectores y cuenta los elementos que hay en cada nivel. Desde ese punto de vista, la matriz contiene tres elementos que a su vez contienen dos, dos y un elementos, lo que da un total de ocho elementos.
Si quisiéramos contar únicamente los valores de una matriz bidimensional podríamos restar los dos resultados anteriores (5 = 8 - 3):
<?php
$datos["pepe"]["edad"] = 25;
$datos["pepe"]["peso"] = 80;
$datos["juan"]["edad"] = 22;
$datos["juan"]["peso"] = 75;
$datos["ana"]["edad"] = 30;
$elementos = count($datos, COUNT_RECURSIVE) - count($datos);
print "<p>La matriz tiene $elementos elementos.</p>\n";
print "\n";
print "<pre>\n"; print_r($datos); print "</pre>\n";
?>
La matriz tiene 5 elementos.
Array ( [pepe] => Array ( [edad] => 25 [peso] => 80 ) [juan] => Array ( [edad] => 22 [peso] => 75 ) [ana] => Array ( [edad] => 30 ) )
En matrices de más dimensiones no podríamos utilizar este procedimiento.
La función array_count_values($matriz) cuenta cuántos valores hay de cada valor de una matriz.
La matriz devuelta tiene como índices los valores de la matriz original y como valores la cantidad de veces que aparece el valor.
<?php
$nombres = ["Ana", "Bernardo", "Bernardo", "Ana", "Carmen", "Ana"];
$cuenta = array_count_values($nombres);
print "<pre>\n"; print_r($cuenta); print "</pre>\n";
?>
Array ( [Ana] => 3 [Bernardo] => 2 [Carmen] => 1 )
La función min($matriz) devuelve el valor mínimo de una matriz no vacía. La función max($matriz) devuelve el valor máximo de una matriz no vacía.
<?php
$numeros = [10, 40, 15, -1];
$maximo = max($numeros);
$minimo = min($numeros);
print "<pre>"; print_r($numeros); print "</pre>\n";
print "\n";
print "<p>El máximo de la matriz es $maximo.</p>\n";
print "\n";
print "<p>El mínimo de la matriz es $minimo.</p>\n";
?>
Array ( [0] => 10 [1] => 40 [2] => 15 [3] => -1 )
El máximo de la matriz es 40.
El mínimo de la matriz es -1.
El manual oficial de PHP desaconseja utilizar esta función si la matriz contiene valores de diferentes tipos (por ejemplo, números y cadenas) ya que las conversiones entre tipos pueden producir resultados inesperados. En general, como PHP convierte los números a cadenas para hacer las comparaciones entre ellos (desde PHP 8.0) y las cadenas van después de los números, el mínimo será uno de los números (el menor) y el máximo una de las cadenas (la última por orden alfabético).
<?php
$valores = [10, "d", 40, "abc"];
$maximo = max($valores);
$minimo = min($valores);
print "<pre>\n"; print_r($valores); print "</pre>\n";
print "\n";
print "<p>El mínimo de la matriz es $minimo.</p>\n";
print "\n";
print "<p>El máximo de la matriz es $maximo.</p>\n";
?>
Array ( [0] => 10 [1] => d [2] => 4 [3] => abc )
El mínimo de la matriz es 4.
El máximo de la matriz es d.
Estas funciones sólo admiten una matriz como argumento. Si se quiere calcular el mínimo o el máximo de varias matrices, deberíamos unir las matrices previamente con array_merge():
<?php
$valores1 = [5, 10, -3];
$valores2 = [19, 9, 2];
$maximo = max(array_merge($valores1, $valores2));
$minimo = min(array_merge($valores1, $valores2));
print "<pre>\n"; print_r($valores1); print "</pre>\n";
print "\n";
print "<pre>\n"; print_r($valores2); print "</pre>\n";
print "\n";
print "<p>El mínimo de las dos matrices es $minimo.</p>\n";
print "\n";
print "<p>El máximo de las dos matrices es $maximo.</p>\n";
?>
Array ( [0] => 5 [1] => 10 [2] => -3 )
Array ( [0] => 19 [1] => 9 [2] => 2 )
El mínimo de las dos matrices es -3.
El máximo de las dos matrices es 19.
Existen varias funciones para ordenar matrices. Las más simples son las siguientes:
<?php
$valores = [5 => "cinco", 1 => "uno", 9 => "nueve"];
print "<p>Matriz inicial:</p>\n";
print "\n";
print "<pre>\n"; print_r($valores); print "</pre>\n";
print "\n";
sort($valores);
print "<p>Matriz ordenada con sort():</p>\n";
print "\n";
print "<pre>\n"; print_r($valores); print "</pre>\n";
print "\n";
?>
Matriz inicial:
Array ( [5] => cinco [1] => uno [9] => nueve )
Matriz ordenada con sort():
Array ( [0] => cinco [1] => nueve [2] => uno )
<?php
$valores = [5 => "cinco", 1 => "uno", 9 => "nueve"];
print "<p>Matriz inicial:</p>\n";
print "\n";
print "<pre>\n"; print_r($valores); print "</pre>\n";
print "\n";
rsort($valores);
print "<p>Matriz ordenada con rsort():</p>\n";
print "\n";
print "<pre>\n"; print_r($valores); print "</pre>\n";
print "\n";
?>
Matriz inicial:
Array ( [5] => cinco [1] => uno [9] => nueve )
Matriz ordenada con rsort():
Array ( [0] => uno [1] => nueve [2] => cinco )
<?php
$valores = [5 => "cinco", 1 => "uno", 9 => "nueve"];
print "<p>Matriz inicial:</p>\n";
print "\n";
print "<pre>\n"; print_r($valores); print "</pre>\n";
print "\n";
asort($valores);
print "<p>Matriz ordenada con asort():</p>\n";
print "\n";
print "<pre>\n"; print_r($valores); print "</pre>\n";
print "\n";
?>
Matriz inicial:
Array ( [5] => cinco [1] => uno [9] => nueve )
Matriz ordenada con asort():
Array ( [5] => cinco [9] => nueve [1] => uno )
<?php
$valores = [5 => "cinco", 1 => "uno", 9 => "nueve"];
print "<p>Matriz inicial:</p>\n";
print "\n";
print "<pre>\n"; print_r($valores); print "</pre>\n";
print "\n";
arsort($valores);
print "<p>Matriz ordenada con arsort():</p>\n";
print "\n";
print "<pre>\n"; print_r($valores); print "</pre>\n";
print "\n";
?>
Matriz inicial:
Array ( [5] => cinco [1] => uno [9] => nueve )
Matriz ordenada con arsort():
Array ( [1] => uno [9] => nueve [5] => cinco )
<?php
$valores = [5 => "cinco", 1 => "uno", 9 => "nueve"];
print "<p>Matriz inicial:</p>\n";
print "\n";
print "<pre>\n"; print_r($valores); print "</pre>\n";
print "\n";
ksort($valores);
print "<p>Matriz ordenada con ksort():</p>\n";
print "\n";
print "<pre>\n"; print_r($valores); print "</pre>\n";
print "\n";
?>
Matriz inicial:
Array ( [5] => cinco [1] => uno [9] => nueve )
Matriz ordenada con ksort():
Array ( [1] => uno [5] => cinco [9] => nueve )
<?php
$valores = [5 => "cinco", 1 => "uno", 9 => "nueve"];
print "<p>Matriz inicial:</p>\n";
print "\n";
print "<pre>\n"; print_r($valores); print "</pre>\n";
print "\n";
krsort($valores);
print "<p>Matriz ordenada con krsort():</p>\n";
print "\n";
print "<pre>\n"; print_r($valores); print "</pre>\n";
print "\n";
?>
Matriz inicial:
Array ( [5] => cinco [1] => uno [9] => nueve )
Matriz ordenada con krsort():
Array ( [9] => nueve [5] => cinco [1] => uno )
Para ver la diferencia entre estas funciones, la tabla siguiente resume los ejemplos anteriores:
Matriz inicial | sort() | rsort() | asort() | arsort() | ksort() | krsort() |
---|---|---|---|---|---|---|
Array ( [5] => cinco [1] => uno [9] => nueve ) |
Array ( [0] => cinco [1] => nueve [2] => uno ) |
Array ( [0] => uno [1] => nueve [2] => cinco ) |
Array ( [5] => cinco [9] => nueve [1] => uno ) |
Array ( [1] => uno [9] => nueve [5] => cinco ) |
Array ( [1] => uno [5] => cinco [9] => nueve ) |
Array ( [9] => nueve [5] => cinco [1] => uno ) |
Si los valores a ordenar son cadenas que contienen caracteres no ingleses, se debe utilizar el segundo argumento con el valor SORT_LOCALE_STRING, aunque también es necesario establecer el idioma con la función setlocale($category, $locales, ...).
Por desgracia, el valor de $locales no es el mismo en Windows que en Linux. Por ejemplo, el locale para España sería "es_ES.UTF-8" en Linux y "es-ES.UTF-8" en Windows.
Las vocales acentuadas se ordenan a continuación de las vocales sin acentuar, salvo si la palabra contiene más letras y entonces son las letras posteriores las que determinan el orden, como muestra el siguiente ejemplo.
<?php
setlocale(LC_ALL, "es-ES.UTF-8");
$valores = ["áb", "ab", "aá", "aa", "aáb", "aab", "aác", "aad", "aae", "aáf"];
print "<p>Matriz inicial:</p>\n";
print "\n";
print "<pre>\n"; print_r($valores); print "</pre>\n";
print "\n";
sort($valores, SORT_LOCALE_STRING);
print "<p>Matriz ordenada con sort():</p>\n";
print "\n";
print "<pre>\n"; print_r($valores); print "</pre>\n";
print "\n";
?>
Array ( [0] => áb [1] => ab [2] => aá [3] => aa [4] => aáb [5] => aab [6] => aác [7] => aad [8] => aae [9] => aáf )
Matriz ordenada con sort():
Array ( [0] => aa [1] => aá [2] => aab [3] => aáb [4] => aác [5] => aad [6] => aae [7] => aáf [8] => ab [9] => áb )
La función booleana in_array($valor, $matriz[, $tipo]) devuelve true si el valor se encuentra en la matriz. Si el argumento booleano $tipo es true, in_array() comprueba además que los tipos coincidan.
<?php
$valores = [10, 40, 15, -1];
print "<pre>\n"; print_r($valores); print "</pre>\n";
if (in_array(15, $valores)) {
print "<p>15 está en la matriz \$valores.</p>\n";
} else {
print "<p>15 no está en la matriz \$valores.</p>\n";
}
print "\n";
if (in_array(25, $valores)) {
print "<p>25 está en la matriz \$valores.</p>\n";
} else {
print "<p>25 no está en la matriz \$valores.</p>\n";
}
print "\n";
if (in_array("15", $valores)) {
print "<p>\"15\" está en la matriz \$valores.</p>\n";
} else {
print "<p>\"15\" no está en la matriz \$valores.</p>\n";
}
print "\n";
if (in_array("15", $valores, true)) {
print "<p>\"15\" está en la matriz \$valores.</p>\n";
} else {
print "<p>\"15\" no está en la matriz \$valores.</p>\n";
}
?>
Array ( [0] => 10 [1] => 40 [2] => 15 [3] => -1 )
15 está en la matriz $valores.
25 no está en la matriz $valores.
"15" está en la matriz $valores.
"15" no está en la matriz $valores.
La función array_search($valor, $matriz[, $tipo]) busca el valor en la matriz y, si lo encuentra, devuelve el índice correspondiente del primer valor que encuentra. Si no lo encuentra, devuelve false.
La función array_keys($matriz[, $valor[, $tipo]) busca el valor en la matriz y, si lo encuentra, devuelve una matriz cuyos valores son los índices de todos los elementos coincidentes. Si no lo encuentra, devuelve una matriz vacía.
<?php
$valores = [10, 40, 15, 30, 15, 40, 15];
print "<pre>\n"; print_r($valores); print "</pre>\n";
print "\n";
$encontrado = array_search(15, $valores);
print "<p>15: $encontrado</p>\n";
print "\n";
$encontrado = array_search(20, $valores);
print "<p>20: $encontrado</p>\n";
print "\n";
$encontrados = array_keys($valores, 15);
print "<pre>\n"; print_r($encontrados); print "</pre>\n";
$encontrados = array_keys($valores, 20);
print "<pre>\n"; print_r($encontrados); print "</pre>\n";
?>
Array ( [0] => 10 [1] => 40 [2] => 15 [3] => 30 [4] => 15 [5] => 40 [6] => 15 )
15: 2
20:
Array ( [0] => 2 [1] => 4 [2] => 6 )
Array ( )
La función array_values($matriz) devuelve los valores de una matriz en el mismo orden que en la matriz original, pero renumerando los índices desde cero
<?php
$nombres = ["a" => "Ana", "c" => "Carmen", 20 => "Bernardo", "c" => "Carmen", "d" => "David", 40 => "Carmen"];
print "<p>Matriz inicial:</p>\n";
print "\n";
print "<pre>\n"; print_r($nombres); print "</pre>\n";
print "\n";
$reindexada = array_values($nombres);
print "<p>Matriz reindexada con array_values():</p>\n";
print "\n";
print "<pre>\n"; print_r($reindexada); print "</pre>\n";
print "\n";
?>
Matriz inicial:
Array ( [a] => Ana [c] => Carmen [20] => Bernardo [d] => David [40] => Carmen )
Matriz reindexada con array_values():
Array ( [0] => Ana [1] => Carmen [2] => Bernardo [3] => David [4] => Carmen )
La función shuffle($matriz) baraja los valores de una matriz. Los índices de la matriz original se pierden, ya que se renumeran desde cero.
<?php
$numeros = [10, 20, 30, 40, 50, 60];
print "<p>Matriz inicial:</p>\n";
print "\n";
print "<pre>\n"; print_r($numeros); print "</pre>\n";
print "\n";
shuffle($numeros);
print "<p>Matriz barajada con shuffle():</p>\n";
print "\n";
print "<pre>\n"; print_r($numeros); print "</pre>\n";
print "\n";
?>
Matriz inicial:
Array ( [0] => 10 [1] => 20 [2] => 30 [3] => 40 [4] => 50 [5] => 60 )
Matriz barajada con shuffle():
Array ( [0] => 30 [1] => 60 [2] => 10 [3] => 20 [4] => 50 [5] => 40 )
<?php
$numeros = ["a" => 10, "b" => 20, "c" => 30, "d" => 40];
print "<p>Matriz inicial:</p>\n";
print "\n";
print "<pre>\n"; print_r($numeros); print "</pre>\n";
print "\n";
shuffle($numeros);
print "<p>Matriz barajada con shuffle():</p>\n";
print "\n";
print "<pre>\n"; print_r($numeros); print "</pre>\n";
print "\n";
?>
Matriz inicial:
Array ( [a] => 10 [b] => 20 [c] => 30 [d] => 40 )
Matriz barajada con shuffle():
Array ( [0] => 20 [1] => 10 [2] => 40 [3] => 30 )
La función array_rand($matriz [,$cantidad]) extrae al azar uno o varios de los índices de la matriz. Una vez obtenido el índice se puede obtener el valor correspondiente de la matriz.
<?php
$cuadrados = [2 => 4, 3 => 9, 7 => 49, 10 => 100];
$indice = array_rand($cuadrados);
print "<pre>\n"; print_r($cuadrados); print "</pre>\n";
print "\n";
print "<p>Índice al azar: $indice</p>\n";
print "\n";
print "<p>Valor al azar: $cuadrados[$indice]</p>\n";
?>
Array ( [2] => 4 [3] => 9 [7] => 49 [10] => 100 )
Índice al azar: 7
Valor al azar: 49
<?php
$cuadrados = [2 => 4, 3 => 9, 7 => 49, 10 => 100, 11 => 121, 15 => 225];
$indices = array_rand($cuadrados, 3);
print "<pre>\n"; print_r($cuadrados); print "</pre>\n";
print "\n";
print "<p>Índices al azar: ";
foreach ($indices as $indice) {
print "$indice ";
}
print "</p>\n";
print "\n";
print "<p>Valores al azar: ";
foreach ($indices as $indice) {
print "$cuadrados[$indice] ";
}
print "</p>\n";
?>
Array ( [2] => 4 [3] => 9 [7] => 49 [10] => 100 [11] => 121 [15] => 225 )
Índices al azar: 2 11 15
Valores al azar: 4 121 225
Si el segundo argumento es 1 (es decir, si sólo se extrae un valor), la función array_rand($matriz, 1) no devuelve una matriz, sino una variable escalar:
<?php
$cuadrados = [2 => 4, 3 => 9, 7 => 49, 10 => 100, 11 => 121, 15 => 225];
$indice = array_rand($cuadrados, 1);
print "<pre>\n"; print_r($cuadrados); print "</pre>\n";
print "\n";
print "<p>Índice al azar: $indice</p>\n";
print "\n";
print "<p>Valor al azar: $cuadrados[$indice]</p>\n";
?>
Array ( [2] => 4 [3] => 9 [7] => 49 [10] => 100 [11] => 121 [15] => 225 )
Índice al azar: 15
Valor al azar: 225
La función array_unique($matriz) devuelve una matriz en la que se han eliminado los valores repetidos.
<?php
$inicial = [0, 0, 1, 3, 1, 3, 2, 1];
$final = array_unique($inicial);
print "<pre>\n"; print_r($final); print "</pre>\n";
?>
Array ( [0] => 0 [2] => 1 [3] => 3 [6] => 2 )