Array duplicado: por que essa tarefa reuniu milhares de visualizações no Stack Overflow
\n\nImagine: você está escrevendo uma loja online, o usuário adiciona produtos ao carrinho. Mas por erro ou devido a um bug, o mesmo iPhone aparece na lista três vezes. Ou você está analisando uma lista de tags de um banco de dados, e "JavaScript" aparece 15 vezes seguidas. O que fazer? Certo — deixar apenas os valores únicos.
\n\nA pergunta "Get all unique values in a JavaScript array (remove duplicates)" no Stack Overflow reuniu centenas de milhares de visualizações. E isso não é por acaso. A tarefa parece simples, mas por baixo dos panos esconde-se todo um arsenal de abordagens: desde one-liners em ES6 moderno até truques engenhosos com filter e indexOf. Neste artigo, não vamos apenas dar soluções prontas, mas analisar como cada uma delas funciona no nível do motor JavaScript.
Pronto para olhar por baixo do capô? Vamos lá!
\n\n\n\n
Método nº1: Set — o rei do desempenho
\n\nA maneira mais elegante e rápida de obter valores únicos em um array JavaScript é usar o objeto Set. Ele surgiu no ES6 e foi literalmente criado para essa tarefa.
const numbers = [1, 2, 2, 3, 4, 4, 5];\nconst uniqueNumbers = [...new Set(numbers)];\n\nconsole.log(uniqueNumbers); // [1, 2, 3, 4, 5]\n\nComo funciona por baixo dos panos?
\nO objeto Set armazena apenas valores únicos. Quando passamos um array para o construtor new Set(numbers), o motor JavaScript percorre cada elemento e o adiciona a uma tabela hash interna. Se o valor já existe — ele é ignorado. Em seguida, o operador de espalhamento ... transforma o Set de volta em um array.
Por que é rápido? Porque a busca e a inserção em um Set são feitas em O(1) (tempo constante). Para um array de 10.000 elementos, a diferença para outros métodos será colossal.
\n\nImportante: O Set preserva a ordem dos elementos, mas funciona apenas com primitivos (números, strings, booleanos). Para objetos, a comparação é por referência, não por conteúdo.
\n\nQuando usar?
\n- \n
- Se o array consiste em números ou strings. \n
- Se a velocidade de processamento de grandes arrays é importante. \n
- Se você está escrevendo código moderno e não tem medo do ES6. \n
\n\n
Método nº2: filter + indexOf — o clássico do gênero
\n\nEste método é um veterano do JavaScript. Funciona em todos os navegadores sem polyfills e ainda é popular no Stack Overflow.
\n\nconst numbers = [1, 2, 2, 3, 4, 4, 5];\nconst uniqueNumbers = numbers.filter((value, index, arr) => {\n return arr.indexOf(value) === index;\n});\n\nconsole.log(uniqueNumbers); // [1, 2, 3, 4, 5]\n\nAnálise da lógica
\nO método filter cria um novo array, mantendo apenas os elementos para os quais o callback retorna true. Dentro do callback, verificamos: o índice atual é a primeira ocorrência desse valor no array? Se sim — mantemos o elemento. Se o valor já apareceu antes — indexOf retornará um índice menor, a condição não será satisfeita e a duplicata será descartada.
Pegadinha: indexOf percorre o array desde o início a cada vez. Isso resulta em complexidade O(n²). Para arrays pequenos (até 1000 elementos), a diferença é imperceptível, mas em 100.000 elementos o navegador pode travar por um segundo.
Quando usar?
\n- \n
- Se precisar suportar navegadores antigos (IE11). \n
- Se o array for pequeno. \n
- Se você quiser mostrar claramente a lógica da "primeira ocorrência". \n
\n\n
Método nº3: reduce + acumulador — flexibilidade e controle
\n\nO método reduce dá controle total sobre o processo. Nós mesmos decidimos como montar o resultado.
const numbers = [1, 2, 2, 3, 4, 4, 5];\nconst uniqueNumbers = numbers.reduce((acc, value) => {\n if (!acc.includes(value)) {\n acc.push