Tenho dois conjuntos de resultados como este:
// Result 1
[
{ value: "0", display: "Jamsheer" },
{ value: "1", display: "Muhammed" },
{ value: "2", display: "Ravi" },
{ value: "3", display: "Ajmal" },
{ value: "4", display: "Ryan" }
]
// Result 2
[
{ value: "0", display: "Jamsheer" },
{ value: "1", display: "Muhammed" },
{ value: "2", display: "Ravi" },
{ value: "3", display: "Ajmal" },
]
O resultado final de que preciso é a diferença entre essas matrizes - o resultado final deve ser assim:
[{ value: "4", display: "Ryan" }]
É possível fazer algo assim em JavaScript?
javascript
arrays
object
BKM
fonte
fonte
Respostas:
Usando apenas JS nativo, algo assim funcionará:
fonte
return a.value ===...
sua resposta? (Boa solução, a propósito, +1) Além de usarArray.prototype.some()
, não consigo encontrar uma maneira mais eficiente / mais curta de fazer isso.true
oufalse
valor.) Neste caso, se separarmos a noção de teste de igualdade do resto do código exigindo que o usuário passe na verificação de igualdade como uma função, podemos fazer um algoritmo genérico direto.Você pode usar
Array.prototype.filter()
em combinação comArray.prototype.some()
.Aqui está um exemplo (assumindo que seus arrays estão armazenados nas variáveis
result1
eresult2
):fonte
Para quem gosta de soluções de uma linha no ES6, algo assim:
fonte
Eu adoto uma abordagem um pouco mais geral, embora semelhante em ideias às abordagens de @Cerbrus e @Kasper Moerch . Eu crio uma função que aceita um predicado para determinar se dois objetos são iguais (aqui nós ignoramos a
$$hashKey
propriedade, mas pode ser qualquer coisa) e retorno uma função que calcula a diferença simétrica de duas listas com base nesse predicado:Tem uma pequena vantagem sobre a abordagem de Cerebrus (assim como a abordagem de Kasper Moerch) por escapar mais cedo; se encontrar uma correspondência, não se preocupa em verificar o resto da lista. Se eu tivesse uma
curry
função útil, faria isso de maneira um pouco diferente, mas funciona bem.Explicação
Um comentário pedia uma explicação mais detalhada para iniciantes. Aqui está uma tentativa.
Passamos a seguinte função para
makeSymmDiffFunc
:Esta função é como decidimos que dois objetos são iguais. Como todas as funções que retornam
true
oufalse
, pode ser chamada de "função de predicado", mas isso é apenas terminologia. O ponto principal é quemakeSymmDiffFunc
se configure com uma função que aceita dois objetos e retornatrue
se os considerarmos iguais,false
se não o fizermos.Usando isso,
makeSymmDiffFunc
(leia "fazer função de diferença simétrica") retorna uma nova função:Esta é a função que realmente usaremos. Passamos duas listas e ele encontra os elementos da primeira, não da segunda, então os da segunda, que não estão na primeira, e combina essas duas listas.
No entanto, olhando novamente, eu poderia definitivamente ter entendido seu código e simplificado a função principal um pouco usando
some
:complement
usa o predicado e retorna os elementos da primeira lista, não da segunda. Isso é mais simples do que minha primeira passagem com umacontains
função separada .Finalmente, a função principal é envolvida em uma expressão de função imediatamente chamada ( IIFE ) para manter a
complement
função interna fora do escopo global.Atualização, alguns anos depois
Agora que o ES2015 se tornou bastante onipresente, eu sugeriria a mesma técnica, com muito menos clichê:
fonte
Isso retornará a diferença entre duas matrizes de objetos, usando a chave
value
para compará-los. Observe que duas coisas com o mesmo valor não serão retornadas, pois as outras chaves são ignoradas.Isso faz parte do lodash .
fonte
Você pode criar um objeto com chaves como o valor exclusivo correspondente para cada objeto na matriz e, em seguida, filtrar cada matriz com base na existência da chave no objeto do outro. Reduz a complexidade da operação.
ES6
ES5
fonte
Acho que a solução @Cerbrus está certa. Eu implementei a mesma solução, mas extraí o código repetido em sua própria função (DRY).
fonte
Eu encontrei essa solução usando filtro e alguns.
fonte
A maioria das respostas aqui são bastante complexas, mas a lógica por trás disso não é muito simples?
Complexidade de O (n ^ 2).
fonte
você pode fazer diff a em be diff b em a, em seguida, mesclar os dois resultados
fonte
Eu fiz um diff generalizado que compara 2 objetos de qualquer tipo e pode executar um manipulador de modificação gist.github.com/bortunac "diff.js" uma ex de usar:
então a propriedade a é modificada, b é excluída, c modificada, d é adicionada
}
agora use como
o console irá mostrar
fonte
Maneira mais genérica e simples:
fonte
Eu prefiro objeto de mapa quando se trata de grandes arrays.
fonte
JavaScript possui mapas, que fornecem tempo de inserção e pesquisa O (1). Portanto, isso pode ser resolvido em O (n) (e não em O (n²) como todas as outras respostas fazem). Para isso, é necessário gerar uma chave primitiva única (string / número) para cada objeto. Pode-se
JSON.stringify
, mas isso é bastante sujeito a erros, pois a ordem dos elementos pode influenciar a igualdade:Portanto, eu pegaria um delimitador que não aparece em nenhum dos valores e compor uma string manualmente:
Em seguida, um mapa é criado. Quando um elemento já existe no Mapa, ele é removido, caso contrário, é adicionado. Portanto, apenas os elementos que são incluídos tempos ímpares (ou seja, apenas uma vez) permanecem. Isso só funcionará se os elementos forem únicos em cada array:
Exibir trecho de código
fonte
Eu me deparei com essa pergunta enquanto procurava uma maneira de escolher o primeiro item em um array que não corresponde a nenhum dos valores em outro array e consegui classificá-lo eventualmente com array.find () e array.filter () como isto
se você precisar buscar uma lista atualizada antes de verificar a próxima melhor opção, isso deve funcionar bem o suficiente :)
fonte
Se você deseja usar bibliotecas externas, pode usar _.difference em underscore.js para fazer isso. _.difference retorna os valores da matriz que não estão presentes nas outras matrizes.
fonte