Eliminar elementos duplicados en un array PHP

Seguro que más de una vez te has encontrado con un array en el que tienes elementos duplicados que quieres eliminar.

Ya que estás leyendo esto, ¿sabías que tengo un Libro de Programación Orientada a Objetos en PHP con contenido tan interesante como el de este post?

Eliminar elementos duplicados en un array PHP multidimensional

PHP incluye una función llamada «array_unique()» que elimina los elementos duplicados. Por desgracia no funciona con arrays multidimensionales.

Así que si tienes un array multidimensional como éste tendrás que crearte tu propia función:

$array = [
    1 => [
        'nombre' => 'Gorka'
    ],
    2 => [
        'nombre' => 'Gorka'
    ],
    3 => [
        'nombre' => 'Jon'
    ],
];

Y la función podría ser algo así:

function elementosUnicos($array)
{
    $arraySinDuplicados = [];
    foreach($array as $indice => $elemento) {
        if (!in_array($elemento, $arraySinDuplicados)) {
            $arraySinDuplicados[$indice] = $elemento;
        }
    }
    return $arraySinDuplicados;
}

Que nos dejaría solo con los elementos deseados:

Array
 (
     [1] => Array
         (
             [nombre] => Gorka
         )
     [3] => Array
         (
             [nombre] => Gorka
         )
 )

Si te fijas esta función respeta los índices del array original. Si no te interesan podrías hacer esta otra:

function elementosUnicos($array)
{
    $arraySinDuplicados = [];
    foreach($array as $elemento) {
        if (!in_array($elemento, $arraySinDuplicados)) {
            $arraySinDuplicados[] = $elemento;
        }
    }
    return $arraySinDuplicados;
}

Y ésta devolvería un array sin respetar los índices originales:

Array
 (
     [0] => Array
         (
             [nombre] => Gorka
         )
     [1] => Array
         (
             [nombre] => Gorka
         )
 )

Otra opción para eliminar duplicados en un array multidimensional

Esto lo ha mandado Manuel Canga a través de Twitter (sacado de StackOverflow):

array_map("unserialize", array_unique(array_map("serialize", $array)));

Me parece una solución muy elegante. Lo que hace es convertir con «serialize» el array multidimensional (array_map(«serialize», $array)):

[1] => a:1:{s:6:"nombre";s:5:"Gorka";}
[2] => a:1:{s:6:"nombre";s:5:"Gorka";}
[3] => a:1:{s:6:"nombre";s:3:"Jon";}

Luego eliminamos los elemtos duplicados con array_unique y por último «des-serializamos» el array.

Eliminar elementos duplicados en array «normal»

Si nuestro array solo tiene una dimensión (un vector) podemos usar la función array_unique() de PHP:

$array = [ 1, 2, 3, 3, 4];

print_r(array_unique($array));
print_r($array);

El segundo print_r() lo he puesto para que se vea que el array original no se modifica. El resultado sería éste:

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

Esta función también funciona con arrays:

$array = [
    'manzana',
    'plátano',
    'pera',
    'pera',
];

print_r(array_unique($array));

Que mostraría:

Array
 (
     [0] => manzana
     [1] => plátano
     [2] => pera
 )

Fíjate que si usamos índices nos quedamos siempre con el primero:

$array = [
    1 => 'manzana',
    2 => 'plátano',
    3 => 'pera',
    10 => 'pera',
];

print_r(array_unique($array));

Como puedes ver el elemento con índice 10 desaparece por ser el «repetido»:

Array
 (
     [1] => manzana
     [2] => plátano
     [3] => pera
 )

Como curiosidad comento que esta función tiene un segundo parámetro que, si te digo la verdad, no se bien para qué sirve. Si descifras qué hacen las constantes SORT_REGULAR, SORT_NUMERIC, SORT_STRING o SORT_LOCALE_STRING avisa.

Deja un comentario