array_unique($array) devuelve el array sin valores duplicados. La primera aparición de cada valor se queda, bajo su clave original, y las copias posteriores se descartan.
El primer resultado conserva las claves 0, 1, 3: las posiciones donde apareció por primera vez cada valor. Envuelve la llamada en array_values() cuando quieras una lista limpia, por ejemplo antes de json_encode.
Cómo decide array_unique que dos valores son iguales
Por defecto, cada valor se convierte en cadena y se comparan las cadenas. Así, 1, "1" y 1.0 cuentan como el mismo valor, y gana el primero. El segundo argumento cambia la comparación.
| Flag | Dos valores son duplicados cuando |
|---|---|
SORT_STRING (por defecto) | (string) $a === (string) $b |
SORT_REGULAR | $a == $b |
SORT_NUMERIC | son iguales como números |
Con el valor por defecto, "01" sobrevive porque la cadena "01" no es la cadena "1". Con SORT_REGULAR se descarta, porque "01" == 1 es verdadero. La comparación flexible también hace que el booleano true coincida con cualquier valor no vacío. Revisa la salida antes de confiar en ella con tipos mezclados; la página de operadores de comparación explica las reglas.
Quitar duplicados sin distinguir mayúsculas y minúsculas
array_unique distingue mayúsculas y minúsculas: "PHP" y "php" son distintos. Para tratarlos como duplicados pero conservar la escritura original del primero, busca las claves únicas en una copia en minúsculas y quédate con esas claves del original.
array_map construye una copia en minúsculas con las mismas claves, array_unique conserva las claves de las primeras apariciones y array_intersect_key toma esas claves del array original. Para texto con tildes o japonés, usa mb_strtolower en lugar de strtolower.
array_unique con un array multidimensional
Sin flag, array_unique convierte cada fila en la cadena "Array", así que todas las filas parecen idénticas y solo sobrevive la primera, con un warning "Array to string conversion" por cada fila. Pasa SORT_REGULAR para comparar filas enteras. Para conservar una fila por cada valor de un solo campo, es más sencillo array_column con null y una clave de índice.
El segundo enfoque conserva la última fila de cada email porque cada fila posterior sobrescribe a la anterior bajo la misma clave. La página de array_column explica la clave de índice en detalle.
Encontrar y contar valores duplicados
array_count_values() devuelve cuántas veces aparece cada valor. Filtra eso por los recuentos mayores que uno y tienes los duplicados.
La última comprobación es una línea habitual para saber si un array tiene algún duplicado.
Valores únicos más rápido con arrays grandes
array_unique convierte cada valor en cadena antes de comparar, lo que va bien con miles de valores. Con una lista grande de enteros o cadenas, invertir el array es más rápido: los valores se convierten en claves, y las claves son únicas por definición.
Los tiempos cambian de una ejecución a otra, pero la versión con flip suele ser varias veces más rápida. Solo funciona con valores que pueden ser claves de array (enteros y cadenas), y las cadenas numéricas como "5" vuelven como enteros.
Preguntas frecuentes
¿array_unique conserva las claves?
Sí. Conserva la primera aparición de cada valor bajo su clave original y descarta las posteriores, así que las claves pueden tener huecos. Usa array_values(array_unique($arr)) para renumerarlas desde 0.
¿Cómo uso array_unique con un array multidimensional?
Pasa SORT_REGULAR para que se comparen filas enteras: array_unique($rows, SORT_REGULAR). Para conservar una fila por cada valor de un campo, como una fila por email, indexa las filas por ese campo: array_column($rows, null, 'email') conserva la última fila de cada email.
¿Cómo elimino duplicados sin distinguir mayúsculas y minúsculas?
Busca las claves únicas en una copia en minúsculas y quédate con esas claves del original: array_intersect_key($arr, array_unique(array_map('strtolower', $arr))). Usa mb_strtolower para texto fuera de ASCII.
¿Cómo encuentro qué valores están duplicados en un array de PHP?
Cuéntalos con array_count_values($arr) y quédate con los recuentos mayores que uno: array_keys(array_filter(array_count_values($arr), fn($n) => $n > 1)). array_count_values solo funciona con cadenas y enteros.