array_unique($array) retorna o array sem os valores duplicados. A primeira ocorrência de cada valor fica, sob a chave original, e as cópias seguintes são descartadas.
O primeiro resultado mantém as chaves 0, 1, 3: as posições em que cada valor apareceu pela primeira vez. Envolva a chamada em array_values() quando quiser uma lista limpa, por exemplo antes do json_encode.
Como o array_unique decide que dois valores são iguais
Por padrão, cada valor é convertido em string e as strings são comparadas. Então 1, "1" e 1.0 contam como o mesmo valor, e o primeiro vence. O segundo argumento muda a comparação.
| Flag | Dois valores são duplicados quando |
|---|---|
SORT_STRING (padrão) | (string) $a === (string) $b |
SORT_REGULAR | $a == $b |
SORT_NUMERIC | são iguais como números |
Com o padrão, "01" sobrevive porque a string "01" não é a string "1". Com SORT_REGULAR ela é descartada, porque "01" == 1 é verdadeiro. A comparação frouxa também deixa o booleano true bater com qualquer valor não vazio. Confira a saída antes de confiar nela com tipos misturados; a página sobre operadores de comparação explica as regras.
Remover duplicados ignorando maiúsculas e minúsculas
O array_unique diferencia maiúsculas de minúsculas: "PHP" e "php" são diferentes. Para tratá-los como duplicados mas manter a grafia original do primeiro, encontre as chaves únicas numa cópia em minúsculas e mantenha essas chaves do original.
O array_map monta uma cópia em minúsculas com as mesmas chaves, o array_unique mantém as chaves das primeiras ocorrências, e o array_intersect_key pega essas chaves do array original. Para texto acentuado ou japonês, use mb_strtolower no lugar de strtolower.
array_unique num array multidimensional
Sem flag, o array_unique converte cada linha na string "Array", então todas as linhas parecem idênticas e só a primeira sobrevive, com um aviso "Array to string conversion" para cada linha. Passe SORT_REGULAR para comparar linhas inteiras. Para manter uma linha por valor de um único campo, array_column com null e uma chave de índice é mais simples.
A segunda abordagem mantém a última linha de cada e-mail porque cada linha posterior sobrescreve a anterior sob a mesma chave. A página sobre array_column explica a chave de índice em detalhe.
Encontrar e contar valores duplicados
O array_count_values() retorna quantas vezes cada valor aparece. Filtre isso para contagens acima de um e você tem os duplicados.
A última verificação é uma linha comum para testar se um array tem algum duplicado.
Valores únicos mais rápidos para arrays grandes
O array_unique converte cada valor em string antes de comparar, o que não é problema para milhares de valores. Para uma lista grande de inteiros ou strings, inverter o array é mais rápido: os valores viram chaves, e chaves são únicas por definição.
Os tempos mudam a cada execução, mas a versão com flip costuma ser várias vezes mais rápida. Ela só funciona para valores que podem ser chaves de array (inteiros e strings), e strings numéricas como "5" voltam como inteiros.
Perguntas frequentes
O array_unique mantém as chaves?
Sim. Ele mantém a primeira ocorrência de cada valor sob a chave original e descarta as seguintes, então as chaves podem ficar com buracos. Use array_values(array_unique($arr)) para renumerá-las a partir de 0.
Como uso array_unique num array multidimensional?
Passe SORT_REGULAR para que linhas inteiras sejam comparadas: array_unique($rows, SORT_REGULAR). Para manter uma linha por valor de um campo, como uma linha por e-mail, indexe as linhas por esse campo: array_column($rows, null, 'email') mantém a última linha de cada e-mail.
Como removo duplicados ignorando maiúsculas e minúsculas?
Encontre as chaves únicas numa cópia em minúsculas e mantenha essas chaves do original: array_intersect_key($arr, array_unique(array_map('strtolower', $arr))). Use mb_strtolower para texto fora do ASCII.
Como descubro quais valores estão repetidos num array PHP?
Conte-os com array_count_values($arr) e mantenha as contagens acima de um: array_keys(array_filter(array_count_values($arr), fn($n) => $n > 1)). O array_count_values só funciona com strings e inteiros.