Matrices

Notación compacta de matrices

En PHP 5.4 (publicado en marzo de 2012) se introdujo en PHP la notación compacta de matrices. Como se explica en la lección Notación clásica de matrices, la diferencia entre ambas notaciones reside en la manera de definir matrices o de añadir valores a una matriz.

A partir del curso 2017/18 en estos apuntes se utilizará la notación compacta en los ejemplos y soluciones de ejercicios, aunque los alumnos pueden utilizar la notación clásica si así lo desean.

Qué es una matriz

Una matriz es un tipo de variable que permite almacenar simultáneamente varios datos diferentes, a los que se accede mediante un índice, numérico o de texto.

En PHP, una matriz es un tipo de variable muy flexible, ya que podemos añadir, modificar, eliminar o reordenar los elementos de forma individual, que pueden ser de tipos de datos diferentes.

En PHP, si:

Crear una matriz

En la notación compacta, las matrices se crean empleando corchetes ([]).

<?php
// Notación compacta
$nombres = ["Ana", "Bernardo", "Carmen"];
?>

Para hacer referencia a los valores individuales de la matriz, se deben utilizar índices, que se escriben entre corchetes ([ ]). Si al crear la matriz no se han indicado otros valores de índices, el primer término tiene el índice [0], el segundo tiene el índice [1], etc.:

PHP sustituye las referencias a valores de matrices de una dimensión dentro de las cadenas, por lo que no es necesario concatenar cadenas y referencias a matrices.

<?php
$nombres = ["Ana", "Bernardo", "Carmen"];

print "<p>$nombres[1]</p>\n";
print "<p>$nombres[0]</p>\n";
?>

Bernardo

Ana


Una vez creada la matriz, los elementos individuales se pueden utilizar como si fueran variables independientes. Pero para referirse a un elemento individual, hay que indicar siempre el índice correspondiente.

<?php
$nombres = ["Ana", "Bernardo", "Carmen"];

print "<p>$nombres[1]</p>\n";

$nombres[1] = "David";

print "<p>$nombres[1]</p>\n";
?>

Bernardo

David


Si se solicita un valor no definido de una matriz, se produce un aviso (undefined offset). Los avisos no interrumpen la ejecución del programa, pero se deben corregir porque el programa seguramente no tendrá el comportamiento esperado:

Incorrecto
<?php
$nombres = ["Ana", "Bernardo", "Carmen"];

print "<p>$nombres[3]<p>\n";
?>

Notice: Undefined offset: 3 in ejemplo.php on line 4


Se puede crear una matriz vacía (para añadirle posteriormente elementos):

<?php
$nombres = [];
?>

También se pueden crear matrices asignando directamente un elemento de la matriz.

<?php
$apellidos[1] = "García";

print "<p>$nombres[1]</p>\n";
?>

García

Matrices asociativas

Las matrices de PHP son matrices asociativas, es decir, que los índices no tienen por qué ser correlativos, ni siquiera tienen por qué ser números.

Al crear matrices asociativas, debemos indicar el valor de los índices, utilizando la notación $indice => $valor:

<?php
$cuadrados = [3 => 9, 5 => 25, 10 => 100];

print "<p>El cuadrado de 3 es $cuadrados[3]</p>\n";
?>

El cuadrado de 3 es 9


PHP sustituye las referencias a valores de matrices de una dimensión dentro de las cadenas, por lo que no es necesario concatenar cadenas y referencias a matrices, pero los índices deben escribirse sin comillas, aunque sean cadenas.

Incorrecto
<?php
$edades = ["Andrés" => 20, "Bárbara" => 19, "Camilo" => 17];

print "<p>Bárbara tiene $edades["Bárbara"] años</p>\n";
?>
Parse error: syntax error, unexpected '"', expecting identifier (T_STRING) or variable (T_VARIABLE) or number (T_NUM_STRING) in ejemplo.php on line 4
Correcto
<?php
$edades = ["Andrés" => 20, "Bárbara" => 19, "Camilo" => 17];

print "<p>Bárbara tiene $edades[Bárbara] años</p>\n";
?>

Bárbara tiene 19 años

Matrices multidimensionales

Las matrices pueden ser multidimensionales, es decir, matrices cuyos elementos son a su vez matrices. Para referirse a los elementos concretos, se necesitan utilizar varios índices (tantos como dimensiones -niveles de anidamiento- tenga la matriz).


PHP no sustituye las referencias a valores de matrices de más de una dimensión dentro de las cadenas, por lo que se necesita o bien utilizar llaves, o bien concatenar cadenas y referencias a matrices. Además, los índices que sean cadenas deben escribirse con comillas.

Incorrecto
<?php
$datos = [
    ["nombre" => "pepe", "edad" => 25, "peso" => 80],
    ["nombre" => "juan", "edad" => 22, "peso" => 75]
];

print "<p>$datos[0][nombre] tiene $datos[0][edad] años.</p>\n";
?>
Notice: Array to string conversion in ejemplo.php on line 6

Notice: Array to string conversion in ejemplo.php on line 6

Array[nombre] tiene Array[edad] años.

Correcto
<?php
$datos = [
    ["nombre" => "pepe", "edad" => 25, "peso" => 80],
    ["nombre" => "juan", "edad" => 22, "peso" => 75]
];

print "<p>{$datos[1]["nombre"]} pesa {$datos[1]["peso"]} kilos</p>\n";

print "<p>" . $datos[0]["nombre"] . " tiene " . $datos[0]["edad"] . " años</p>\n";
?>

pepe tiene 25 años

juan pesa 75 kilos

Imprimir todos los valores de una matriz: la función print_r()

La instrucción print permite imprimir valores individuales de una matriz, pero no matrices completas.

Incorrecto
<?php
$datos["nombre"] = "Santiago";
$datos["apellidos"] = "Ramón y Cajal";

print "$datos";
?>
Notice: Array to string conversion in ejemplo.php on line 5
Array

La función print_r($variable [, $devolver]) permite imprimir todos los valores de una matriz de forma estructura. En general, print_r() imprime cualquier variable variable de forma legible.

Aunque print_r() genera espacios y saltos de línea que pueden verse en el código fuente de la página, print_r() no genera etiquetas html, por lo que el navegador no muestra esos espacios y saltos de línea.

<?php
$datos["nombre"] = "Santiago";
$datos["apellidos"] = "Ramón y Cajal";

print_r($datos);
?>
Array ( [nombre] => Santiago [apellidos] => Ramón y Cajal )

Para mejorar la legibilidad una solución es añadir la etiqueta <pre>, que fuerza al navegador a mostrar los espacios y saltos de línea.

<?php
$datos["nombre"] = "Santiago";
$datos["apellidos"] = "Ramón y Cajal";

print "<pre>";
print_r($datos);
print "</pre>";
?>
Array
(
    [nombre] => Santiago
    [apellidos] => Ramón y Cajal
)
<?php
$datos[1]["nombre"] = "Santiago";
$datos[1]["apellidos"] = "Ramón y Cajal";
$datos[2]["nombre"] = "Leonardo";
$datos[2]["apellidos"] = "Torres Quevedo";

print "<pre>";
print_r($datos);
print "</pre>";
?>
Array
(
    [1] => Array
        (
            [nombre] => Santiago
            [apellidos] => Ramón y Cajal
        )

    [2] => Array
        (
            [nombre] => Leonardo
            [apellidos] => Torres Quevedo
        )
)

Si se añade un segundo argumento con el valor true, print_r() no imprime nada pero devuelve el texto que se imprimiría si no estuviera el argumento true. Se utiliza para guardar la respuesta en una variable que se puede imprimir posteriormente

<?php
$datos["nombre"] = "Santiago";
$datos["apellidos"] = "Ramón y Cajal";

$tmp = print_r($datos, true);
print "<p>La matriz es $tmp</p>\n";
?>

La matriz es Array ( [nombre] => Santiago [apellidos] => Ramón y Cajal )

<?php
$datos["nombre"] = "Santiago";
$datos["apellidos"] = "Ramón y Cajal";

print "<p>La matriz es " . print_r($datos, true) . "</p>\n";
?>

La matriz es Array ( [nombre] => Santiago [apellidos] => Ramón y Cajal )


La notación con llaves ({}) no admite la función print_r():

Incorrecto
<?php
$datos["nombre"] = "Santiago";
$datos["apellidos"] = "Ramón y Cajal";

print "<p>La matriz es {print_r($datos, true)}</p>\n";
?>
Notice: Array to string conversion in ejemplo.php on line 5

La matriz es {print_r(Array, true)}

Añadir elementos a una matriz

En la notación compacta, se pueden añadir elementos a una matriz indicando o no el índice del nuevo elemento:

Más información general sobre las matrices

Cada elemento de la matriz se comporta como una variable independiente y se pueden almacenar datos de tipos distintos en una misma matriz.

<?php
$datos = ["Santiago", "Ramón y Cajal", 1852];

print "<p>$datos[0] $datos[1] nació en $datos[2].<p>\n";
?>

Santiago Ramón y Cajal nació en 1852.


Los valores de los índices numéricos suelen ser siempre positivos, pero PHP también permite que sean negativos, aunque hay que tener cuidado al imprimirlos:

Incorrecto
<?php
$nombres[-3] = "Hola";

print "<p>$nombres[-3]<p>\n";
?>
Parse error: syntax error, unexpected '-', expecting identifier (T_STRING) or variable (T_VARIABLE) or number (T_NUM_STRING) in ejemplo.php on line 3
Correcto
<?php
$nombres[-3] = "Alba";

print "<p>{$nombres[-3]}<p>\n";
print "<p>" . $nombres[-3] . "<p>\n";
?>

Alba

Alba

PHP no permite valores decimales en los índices numéricos. En caso de usarlos, PHP los trunca automáticamente a enteros (por lo que se recomienda utilizarlos con cuidado):

<?php
$nombres[1.7] = "Alba";

print "<p>$nombres[1]<p>\n";
?>

Alba

<?php
$nombres[1.7] = "Alba";

print "<p>" . $nombres[1.2] ."<p>\n";
?>

Alba

Como en el caso de los negativos, hay que tener cuidado al imprimirlos:

Incorrecto
<?php
$nombres[1.7] = "Alba";

print "<p>$nombres[1.7]<p>\n";
?>
Parse error: syntax error, unexpected '.', expecting ']' in ejemplo.php on line 3
Correcto
<?php
$nombres[1.7] = "Alba";

print "<p>{$nombres[1.2]}<p>\n";
print "<p>" . $nombres[1.2] ."<p>\n";
?>

Alba

Alba


En el caso de las matrices multidimensionales, la misma información se puede guardar de varias formas distintas.

<?php
$datos["pepe"]["edad"] = 25;
$datos["pepe"]["peso"] = 80;
$datos["juan"]["edad"] = 22;
$datos["juan"]["peso"] = 75;

print "<pre>\n"; print_r($datos); print "</pre>\n";
?>
Array
(
    [pepe] => Array
        (
            [edad] => 25
            [peso] => 80
        )

    [juan] => Array
        (
            [edad] => 22
            [peso] => 75
        )

)

En el ejemplo anterior se ha utilizado el nombre de la persona como índice de la matriz, lo que no es una buena idea, ya que no podríamos guardar los datos de dos personas con el mismo nombre. Sería mejor guardar la información de manera similar a como se guardaría en una base de datos. Una matriz de dos dimensiones sería en ese caso el equivalente a una tabla, el primer índice correspondería al número de registro y el segundo índice iría tomando los valores de los campos de la tabla (nombre, edad, peso, etc).

<?php
$datos[0]["nombre"] = "pepe";
$datos[0]["edad"] = 25;
$datos[0]["peso"] = 80;
$datos[1]["nombre"] = "juan";
$datos[1]["edad"] = 22;
$datos[1]["peso"] = 75;

print "<pre>\n"; print_r($datos); print "</pre>\n";
?>
Array
(
    [0] => Array
        (
            [nombre] => pepe
            [edad] => 25
            [peso] => 80
        )

    [1] => Array
        (
            [nombre] => juan
            [edad] => 22
            [peso] => 75
        )

)

Borrar una matriz o elementos de una matriz

La función unset() permite borrar una matriz o elementos de una matriz.

<?php
$matriz = [5 => 25, -1 => "negativo", "número 1" => "cinco"];

print "<pre>\n"; print_r($matriz); print "</pre>\n";

unset($matriz[5]);

print "<pre>\n"; print_r($matriz); print "</pre>\n";
?>
Array
(
    [5] => 25
    [-1] => negativo
    [número 1] => cinco
)

Array
(
    [-1] => negativo
    [número 1] => cinco
)       
<?php
$matriz = [5 => 25, -1 => "negativo", "número 1" => "cinco"];

print "<pre>\n"; print_r($matriz); print "</pre>\n";

unset($matriz);

print "<pre>\n"; print_r($matriz); print "</pre>\n";
?>
Array
(
    [5] => 25
    [-1] => negativo
    [número 1] => cinco
)

Notice:  Undefined variable: matriz in prueba.php on line 8
        

Si se intenta borrar un elemento no definido, PHP no genera ningún aviso.

<?php
$nombres = ["Alba", "Bernardo"];

print "<pre>\n"; print_r($nombres); print "</pre>\n";

unset($matriz[3]);

print "<pre>\n"; print_r($nombres); print "</pre>\n";
?>
Array
(
    [0] => Alba
    [1] => Bernardo
)
Array
(
    [0] => Alba
    [1] => Bernardo
)

Copiar una matriz

Se puede copiar una matriz creando una nueva variable. Las dos matrices son independientes, por lo que modificar posteriormente una de ellas no afecta a la otra.

<?php
$cuadrados = [5 => 25, 9 => 81];

$cuadradosCopia = $cuadrados;

$cuadrados[] = 100;

print "<p>Matriz inicial (modificada):</p>\n";
print "<pre>\n"; print_r($cuadrados); print "</pre>\n\n";

print "<p>Copia de la matriz inicial (sin modificar):</p>\n";
print "<pre>\n"; print_r($cuadradosCopia); print "</pre>\n";
?>

Matriz inicial (modificada):

Array
(
    [5] => 25
    [9] => 81
    [10] => 100
)

Copia de la matriz inicial (sin modificar):

Array
(
    [5] => 25
    [9] => 81
)

Contar elementos de una matriz

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 "<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 "<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, habría que 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 "<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 quisieramos contar únicamente los elementos de una matriz bidimensional habría que 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 "<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
        )

)

Máximo y mínimo

La función max($matriz, ...) devuelve el valor máximo de una matriz (o varias). La función min($matriz, ...) devuelve el valor mínimo de una matriz (o varias).

<?php
$numeros = [10, 40, 15, -1];

$maximo = max($numeros);
$minimo = min($numeros);

print "<pre>"; print_r($numeros); print "</pre>\n";
print "<p>El máximo de la matriz es $maximo.</p>\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.

Los valores no numéricos se tratan como 0, pero si 0 es el mínimo o el máximo, la función devuelve la cadena.

<?php
$valores = [10, 40, 15, "abc"];

$maximo = max($valores);
$minimo = min($valores);

print "<pre>\n"; print_r($valores); print "</pre>\n";
print "<p>El máximo de la matriz es $maximo.</p>\n";
print "<p>El mínimo de la matriz es $minimo.</p>\n";
?>
Array
(
    [0] => 10
    [1] => 40
    [2] => 15
    [3] => abc
)

El máximo de la matriz es 40.

El mínimo de la matriz es abc.

Ordenar una matriz

Existen varias funciones para ordenar matrices. Las más simples son las siguientes:

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
)

Buscar un valor en una matriz

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";
}

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";
}

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" 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, pero si hay varios valores coincidente sólo devuelve el primero que encuentra.

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.

<?php
$valores = [10, 40, 15, 30, 15, 40, 15];

print "<pre>\n"; print_r($valores); print "</pre>\n";

$encontrado = array_search(15, $valores);
print "<p>$encontrado</p>\n";

$encontrados = array_keys($valores, 15);
print "<pre>\n"; print_r($encontrados); print "</pre>\n";
?>
Array
(
    [0] => 10
    [1] => 40
    [2] => 15
    [3] => 30
    [4] => 15
    [5] => 40
    [6] => 15
)

2

Array
(
    [0] => 2
    [1] => 4
    [2] => 6
)

Reindexar una matriz

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", "b" => "Bernardo", "c" => "Carmen", "d" => "David"];

print "<p>Matriz inicial:</p>\n\n";
print "<pre>\n"; print_r($nombres); print "</pre>\n\n";

$reindexada = array_values($nombres);

print "<p>Matriz reindexada con array_values():</p>\n\n";
print "<pre>\n"; print_r($reindexada); print "</pre>\n\n";
?>

Matriz inicial:

Array
(
    [a] => Ana
    [b] => Bernardo
    [c] => Carmen
    [d] => David
)

Matriz reindexada con array_values():

Array
(
    [0] => Ana
    [1] => Bernardo
    [2] => Carmen
    [3] => David
)

Barajar los elementos de una matriz

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 = [0, 1, 2, 3, 4, 5];

print "<p>Matriz inicial:</p>\n\n";
print "<pre>\n"; print_r($numeros); print "</pre>\n\n";

shuffle($numeros);

print "<p>Matriz barajada con shuffle():</p>\n\n";
print "<pre>\n"; print_r($numeros); print "</pre>\n\n";
?>

Matriz inicial:

Array
(
    [0] => 0
    [1] => 1
    [2] => 2
    [3] => 3
    [4] => 4
    [5] => 5
)

Matriz barajada con shuffle():

Array
(
    [0] => 3
    [1] => 1
    [2] => 5
    [3] => 0
    [4] => 4
    [5] => 2
)
<?php
$numeros = ["a" => 1, "b" => 2, "c" => 3, "d" => 4];

print "<p>Matriz inicial:</p>\n\n";
print "<pre>\n"; print_r($numeros); print "</pre>\n\n";

shuffle($numeros);

print "<p>Matriz barajada con shuffle():</p>\n\n";
print "<pre>\n"; print_r($numeros); print "</pre>\n\n";
?>

Matriz inicial:

Array
(
    [a] => 1
    [b] => 2
    [c] => 3
    [d] => 4
)

Matriz barajada con shuffle():

Array
(
    [0] => 2
    [1] => 1
    [2] => 4
    [3] => 3
)