Como posso obter uma lista de valores exclusivos em uma matriz? Eu sempre tenho que usar uma segunda matriz ou há algo semelhante ao hashmap de java em JavaScript?
Vou usar apenas JavaScript e jQuery . Nenhuma biblioteca adicional pode ser usada.
javascript
jquery
Astronauta
fonte
fonte
underscore.js
biblioteca?list.toSet
Respostas:
Desde que eu falei sobre isso nos comentários da resposta do @ Rocket, também posso fornecer um exemplo que não usa bibliotecas. Isso requer duas novas funções de protótipo
contains
eunique
Para obter mais confiabilidade, você pode substituir
contains
peloindexOf
calço do MDN e verificar se cada elementoindexOf
é igual a -1: documentationfonte
~a.indexOf(b) === (a.indexOf(b) == -1)
if (~a.indexOf(b)) ...
é idêntico a escrever por mais tempoif (a.indexOf(b) == -1) ...
.Ou para quem procura uma linha (simples e funcional), compatível com os navegadores atuais :
Atualização 18-04-2017
Parece que 'Array.prototype.includes' agora tem amplo suporte nas versões mais recentes dos navegadores principais ( compatibilidade )
Atualização 29-07-2015:
Existem planos em andamento para os navegadores oferecerem suporte a um método padronizado 'Array.prototype.includes', que, embora não responda diretamente a essa pergunta; é frequentemente relacionado.
Uso:
Pollyfill ( suporte ao navegador , fonte do mozilla ):
fonte
Aqui está uma solução muito mais limpa para o ES6 que eu vejo que não está incluída aqui. Ele usa o conjunto e o operador de propagação :
...
Que retorna
[1, 2]
fonte
Array.from(... new Set(a))
pois Set não pode ser convertido implicitamente em um tipo de matriz. Apenas um alerta!Array.from(new Set(a))
? Isso parece funcionar.One Liner, JavaScript puro
Com sintaxe ES6
list = list.filter((x, i, a) => a.indexOf(x) === i)
Com sintaxe ES5
Compatibilidade do Navegador : IE9 +
fonte
a.indexOf(x) === i
nota de igualdade dos três sinais de igualdade.Usando o EcmaScript 2016, você pode simplesmente fazer assim.
Os conjuntos são sempre exclusivos e, com
Array.from()
o uso, você pode converter um conjunto em uma matriz. Para referência, dê uma olhada nas documentações.https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects /Conjunto
fonte
indexOf()
as respostas são terríveis porque são O (N ^ 2). As respostas de propagação estão ok, mas não funcionam para matrizes grandes. Essa é a melhor abordagem.Agora no ES6, podemos usar a recém-introduzida função ES6
OR by Array espalhar sintaxe em iterables
Retornará o resultado exclusivo.
fonte
new Set
como este (como moderno angular / typescript)let items = [1,1,1,1,3,4,5,2,23,1,4,4,4,2,2,2];
let uniqueItems = [...new Set(items)];
Se você quiser deixar a matriz original intacta,
você precisa de uma segunda matriz para conter os elementos uniqe do primeiro
A maioria dos navegadores possui
Array.prototype.filter
:fonte
Hoje em dia, você pode usar o tipo de dados Set do ES6 para converter sua matriz em um conjunto exclusivo. Então, se você precisar usar métodos de matriz, poderá transformá-lo novamente em uma matriz:
fonte
var uniqueArr = [...new Set(arr)]; // ["a", "b"]
Não é nativo em Javascript, mas muitas bibliotecas têm esse método.
Das Underscore.js
_.uniq(array)
( ligação ) funciona muito bem ( fonte ).fonte
Usando jQuery, aqui está uma função exclusiva de matriz que eu criei:
fonte
$.uniqueArray(arr)
? Incorporação referências a jQuery dentroArray
protótipo 's parece questionável$.uniqueArray
depende do jQuery; menos óbvio queArray.prototype.unique
é também.prototype
s. Mas, eu entendo o seu ponto agora. Vou deixar isso aqui de qualquer maneira.Solução curta e doce usando segunda matriz;
fonte
Rápido, compacto, sem loops aninhados, funciona com qualquer objeto, não apenas com strings e números, assume um predicado e apenas 5 linhas de código !!
Exemplo: para encontrar itens exclusivos por tipo:
Se você deseja que ele encontre o primeiro item exclusivo em vez do último, adicione um check found.hasOwnPropery () lá.
fonte
Você só precisa do vanilla JS para encontrar itens únicos com Array.some e Array.reduce. Com a sintaxe do ES2015, são apenas 62 caracteres.
Array.some e Array.reduce são suportados no IE9 + e em outros navegadores. Basta alterar as funções de seta gorda para obter funções regulares para suporte em navegadores que não suportam a sintaxe do ES2015.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects / Matriz / Reduzir
fonte
A maioria das soluções acima tem uma alta complexidade de tempo de execução.
Aqui está a solução que usa
reduce
e pode fazer o trabalho em O (n) tempo.Nota:
Esta solução não depende de redução. A idéia é criar um mapa de objetos e inserir mapas exclusivos na matriz.
fonte
ES6 maneira:
fonte
você pode usar,
isso lhe dará elementos únicos,
**> mas há um problema,
A segunda opção é usar o método de filtro na matriz.
fonte
Você pode inserir a matriz com duplicatas e o método abaixo retornará a matriz com elementos exclusivos.
fonte
O único problema com as soluções dadas até agora é a eficiência. Se você está preocupado com isso (e provavelmente deveria), precisa evitar loops aninhados: para * for, filter * indexOf, grep * inArray, todos iteram a matriz várias vezes. Você pode implementar um único loop com soluções como esta ou esta
fonte
fonte
Eu tentei esse problema em JS puro. Eu segui as etapas a seguir 1. Classifique a matriz fornecida, 2. faça um loop na matriz classificada, 3. Verifique o valor anterior e o próximo valor com o valor atual
Demo
fonte
fonte
Tendo em mente que
indexOf
retornará a primeira ocorrência de um elemento, você pode fazer algo assim:fonte
Se você não precisa se preocupar tanto com navegadores antigos, é exatamente para isso que os Sets são projetados.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
fonte
Outro pensamento sobre esta questão. Aqui está o que eu fiz para conseguir isso com menos código.
fonte
fonte
Aqui está uma abordagem com
equals
função personalizável que pode ser usada para primitivos e também para objetos personalizados:uso:
fonte
Minha resposta usa
Array.filter
eArray.indexOf
métodos para obter valores únicosEu vi essa abordagem em um site, mas o código deles é diferente do que parece aqui. Simplifiquei o código para uma linha e publiquei aqui para que alguém se beneficie dele
Nota: Minha abordagem é semelhante ou igual à liner postada por Josh. Estou deixando aqui, pois os nomes das variáveis são auto-explicativos no meu código.
fonte
Eu só estava pensando se podemos usar a pesquisa linear para eliminar as duplicatas:
}
HTML:
fonte
Aqui está a solução única para o problema:
Copie e cole isso no console do navegador e obtenha os resultados, yo :-)
fonte
Eu tenho a função JQuery Unique embutida.
Para mais, consulte a documentação da API do jquery.
http://api.jquery.com/jquery.unique/
fonte