Eu tenho duas matrizes JavaScript:
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
Eu quero que a saída seja:
var array3 = ["Vijendra","Singh","Shakya"];
A matriz de saída deve ter palavras repetidas removidas.
Como mesclar duas matrizes em JavaScript para obter apenas os itens exclusivos de cada matriz na mesma ordem em que foram inseridos nas matrizes originais?
javascript
arrays
merge
Vijjendra
fonte
fonte
Respostas:
Para mesclar apenas as matrizes (sem remover duplicatas)
Uso da versão ES5
Array.concat
:Versão ES6 usa desestruturação
Como não existe uma maneira 'incorporada' para remover duplicatas (o ECMA-262 realmente possui o
Array.forEach
que seria ótimo para isso), precisamos fazer isso manualmente:Então, para usá-lo:
Isso também preservará a ordem das matrizes (ou seja, nenhuma classificação é necessária).
Como muitas pessoas se incomodam com o aumento de protótipos
Array.prototype
efor in
loops, eis uma maneira menos invasiva de usá-lo:Para aqueles que têm a sorte de trabalhar com navegadores onde o ES5 está disponível, você pode usar o
Object.defineProperty
seguinte:fonte
[a, b, c]
e[x, b, d]
ser as matrizes (assumir aspas). concat dá[a, b, c, x, b, d]
. A saída do unique () não seria[a, c, x, b, d]
. Isso não preservar a ordem eu acho - eu acredito OP quer[a, b, c, x, d]
for ... in
comhasOwnProperty
caso em que o método protótipo é bomCom Underscore.js ou Lo-Dash, você pode:
http://underscorejs.org/#union
http://lodash.com/docs#union
fonte
underscore.flatten()
que é melhor que a união, pois é preciso uma matriz de matrizes.Primeiro concatene as duas matrizes, depois filtre apenas os itens exclusivos:
Editar
Conforme sugerido, uma solução mais inteligente em termos de desempenho seria filtrar os itens exclusivos
b
antes de concatenar coma
:fonte
a
para adicionarb
, será melhor fazer um loop e usar push?a.forEach(function(item){ if(a.indexOf(item)<0) a.push(item); });
var c = [...a, ...b.filter(o => !~a.indexOf(o))];
2.var c = [...new Set([...a, ...b])];
☺Esta é uma solução ECMAScript 6 usando operadores de propagação e genéricos de matriz.
Atualmente, ele funciona apenas com o Firefox e, possivelmente, com o Internet Explorer Technical Preview.
Mas se você usa Babel , pode obtê-lo agora.
fonte
Array.from
pode ser usado em vez de operador de propagação:Array.from(new Set([].concat(...arr)))
ES6
OU
OU
fonte
union
+ 1º exemplo explode a pilha paraArray
s grandes + 3º exemplo é incrivelmente lento e consome muita memória, pois doisArray
s intermediários precisam ser construídos + 3º exemplo só pode ser usadounion
com um conhecido número deArray
s em tempo de compilação.Set
é o caminho a percorrer aquiUsando um conjunto (ECMAScript 2015), será tão simples quanto isso:
fonte
const array3 = [...new Set(array1.concat(array2))]
Aqui está uma visão ligeiramente diferente do loop. Com algumas das otimizações da versão mais recente do Chrome, é o método mais rápido para resolver a união das duas matrizes (Chrome 38.0.2111).
http://jsperf.com/merge-two-arrays-keeping-only-unique-values
while loop: ~ 589k ops / s
filter: ~ 445k ops / s
lodash: 308k ops / s
para loops: 225k ops / s
Um comentário apontou que uma das minhas variáveis de instalação estava fazendo com que meu loop se destacasse do restante, porque não era necessário inicializar uma matriz vazia para gravar. Eu concordo com isso, então reescrevi o teste até o campo de jogo e incluí uma opção ainda mais rápida.
http://jsperf.com/merge-two-arrays-keeping-only-unique-values/52
Nesta solução alternativa, eu combinei a solução de matriz associativa de uma resposta para eliminar a
.indexOf()
chamada no loop, que estava atrasando bastante as coisas com um segundo loop, e incluí algumas das outras otimizações que outros usuários sugeriram em suas respostas também .A resposta principal aqui com o loop duplo em todos os valores (i-1) ainda é significativamente mais lenta. O lodash ainda está forte, e eu ainda o recomendaria para quem não se importa de adicionar uma biblioteca ao seu projeto. Para aqueles que não querem, meu loop while ainda é uma boa resposta e a resposta do filtro tem uma exibição muito forte aqui, superando todos os meus testes com o mais recente Canary Chrome (44.0.2360) até o momento.
Confira a resposta de Mike e resposta de Dan Stocker se você quiser intensificar-se um entalhe em velocidade. Esses são, de longe, o mais rápido de todos os resultados, depois de passarmos por quase todas as respostas viáveis.
fonte
Você pode fazer isso simplesmente com o ECMAScript 6,
fonte
Array.from(new Set(array1.concat(array2)))
.tsconfig.json
, você pode adicionar"downlevelIteration": true
acompilerOptions
.Uma função de mesclagem de matriz muito melhor.
fonte
var test = ['a', 'b', 'c']; console.log(test);
será impresso["a", "b", "c", merge: function]
Apenas jogando meus dois centavos.
Este é um método que eu uso muito, ele usa um objeto como uma tabela de hashlookup para fazer a verificação duplicada. Supondo que o hash seja O (1), então ele é executado em O (n) onde n é a.length + b.length. Sinceramente, não tenho ideia de como o navegador faz o hash, mas ele tem um bom desempenho em muitos milhares de pontos de dados.
fonte
String()
função em javascript. O que pode funcionar para valores primitivos (embora com colisões entre tipos), mas não é adequado para matrizes de objetos.Apenas evite os loops aninhados (O (n ^ 2)) e
.indexOf()
(+ O (n)).fonte
Simplificou o melhor desta resposta e transformou-a em uma boa função:
fonte
Por que você não usa um objeto? Parece que você está tentando modelar um conjunto. Isso não preservará a ordem, no entanto.
fonte
if (!set1.hasOwnProperty(key))
?A melhor solução...
Você pode verificar diretamente no console do navegador pressionando ...
Sem duplicado
Com duplicado
Se você quiser sem duplicar, pode tentar uma solução melhor a partir daqui - Shouting Code .
Experimente no console do navegador Chrome
Resultado:
fonte
Meu centavo e meio:
fonte
Você pode consegui-lo simplesmente usando o Underscore.js = => uniq :
Ele imprimirá ["Vijendra", "Singh", "Shakya"] .
fonte
Para o ES6, apenas uma linha:
fonte
Eu sei que essa pergunta não é sobre matriz de objetos, mas os pesquisadores acabam aqui.
portanto, vale a pena adicionar aos futuros leitores uma maneira adequada de mesclar ES6 e remover duplicatas
matriz de objetos :
fonte
A implementação do
indexOf
método para outros navegadores é obtida do MDCfonte
from
parâmetro btw?indexOf
. Limpou o código removendo a parte comentada. @ medidor - obrigado novamente.Nova solução (que usa
Array.prototype.indexOf
eArray.prototype.concat
):Uso:
Array.prototype.indexOf (para Internet Explorer):
fonte
Isso pode ser feito usando Set.
fonte
Existem muitas soluções para mesclar duas matrizes. Eles podem ser divididos em duas categorias principais (exceto o uso de bibliotecas de terceiros, como lodash ou underscore.js).
a) combine duas matrizes e remova itens duplicados.
b) filtre os itens antes de combiná-los.
Combine duas matrizes e remova itens duplicados
Combinando
Unificando
Existem várias maneiras de unificar uma matriz, eu pessoalmente sugiro abaixo dois métodos.
Filtrar itens antes de combiná-los
Existem também várias maneiras, mas eu pessoalmente sugiro o código abaixo devido à sua simplicidade.
fonte
fonte
A coisa boa sobre este é o desempenho e que você, em geral, ao trabalhar com matrizes, está encadeando métodos como filtro, mapa, etc. um (quando você está encadeando métodos que não possui), exemplo:
(Não gosto de poluir o Array.prototype e essa seria a única maneira de respeitar a cadeia - definir uma nova função a interromperá -, então acho que algo assim é a única maneira de conseguir isso)
fonte
Você pode tentar isso:
fonte
Uma abordagem funcional com o ES2015
Seguindo a abordagem funcional, a
union
de doisArray
s é apenas a composição deconcat
efilter
. Para fornecer um desempenho ideal, recorremos aoSet
tipo de dados nativo , que é otimizado para pesquisas de propriedades.De qualquer forma, a questão principal em conjunto com uma
union
função é como tratar duplicatas. As seguintes permutações são possíveis:As duas primeiras permutações são fáceis de manusear com uma única função. No entanto, os dois últimos são mais complicados, pois você não pode processá-los enquanto confiar nas
Set
pesquisas. Como a mudança paraObject
pesquisas simples de propriedades antigas implicaria um sério desempenho, a implementação a seguir ignora a terceira e quarta permutação. Você precisaria criar uma versão separadaunion
para suportá-los.A partir daqui, torna-se trivial implementar uma
unionn
função que aceita qualquer número de matrizes (inspiradas nos comentários de naomik):Acontece que
unionn
é apenasfoldl
(akaArray.prototype.reduce
), que assumeunion
como seu redutor. Nota: Como a implementação não usa um acumulador adicional, gera um erro quando você a aplica sem argumentos.fonte
flip
enotf
não são utilizados. TambémunionBy
predicam detalhes de implementação de vazamentos (requer conhecimento implícito doSet
tipo). Pode ser bom se você pudesse fazer algo assim:union = unionBy (apply)
eunionci = unionBy (p => x => p(x.toLowerCase()))
. Dessa forma, o usuário envia apenas o valor do agrupamentop
- apenas uma idéia ^ _ ^zs
declaração de variável também não possuivar
/let
palavrapor uma questão de ... aqui está uma solução de linha única:
Não é particularmente legível, mas pode ajudar alguém:
Set
.Set
em uma matriz.sort()
função é aplicada à nova matriz.fonte
reduce()
você pode usarArray.from(set)
Desduplicar entradas simples ou Mesclar e Desduplicar várias matrizes. Exemplo abaixo.
usando ES6 - Defina, para, desestruturação
Eu escrevi essa função simples que recebe vários argumentos de matriz. Faz praticamente o mesmo que a solução acima, apenas possui casos de uso mais práticos. Essa função não concatena valores duplicados em uma matriz apenas para que possa excluí-los em algum estágio posterior.
DEFINIÇÃO DE CURTA FUNÇÃO (apenas 9 linhas)
EXEMPLO DE USO CODEPEN :
fonte
arr.map
aqui? Você está usando-o como umforeach
, pois o resultado é ignoradofonte
fonte