Vale lembrar que Set
, segundo a especificação da linguagem, não é um método, e sim um objeto.
Além disso, ele só funciona da forma esperada com tipos primitivos (números, strings, booleanos, entre outros). Mas se usarmos objetos, já não funciona:
const array = [
{ nome: 'Fulano', idade: 42 },
{ nome: 'Ciclano', idade: 21 },
{ nome: 'Fulano', idade: 42 } // duplicado, deveria ser eliminado no Set (mas não é)
];
const unique = Array.from(new Set(array));
console.log(unique); // contém todos os 3 elementos
Isso porque o Set
trabalha com referências ao objeto, em vez de olhar para o seu conteúdo. No caso, mesmo se criarmos um objeto com os mesmos valores, ele será outro objeto, e portanto outra referência. Por isso o Set
considera que são objetos diferentes.
Uma alternativa, nesse caso, é usar um Map
. Para cada elemento, geramos uma chave concatenando o nome e idade (que são os valores que consideramos para comparar dois objetos), e em seguida adicionamos no Map
. Se a chave já existir, ele não é adicionado novamente, então nem precisamos verificar se ele já existe. Por fim, basta pegar os valores e criar o array final:
const array = [
{ nome: 'Fulano', idade: 42 },
{ nome: 'Ciclano', idade: 21 },
{ nome: 'Fulano', idade: 42 }
];
const map = new Map();
for (const item of array) {
// nome e idade são os valores para consideramos um objeto "único"
const key = `${item.nome}_${item.idade}`;
map.set(key, item); // se já existir no Map, ele não sobrescreve o anterior (o que dá na mesma, já que são os mesmos valores)
}
const unique = Array.from(map.values());
console.log(unique); // [ { nome: 'Fulano', idade: 42 }, { nome: 'Ciclano', idade: 21 } ]