Eu tenho 2 objetos aninhados que são diferentes e preciso saber se eles têm diferença em uma de suas propriedades aninhadas.
var a = {};
var b = {};
a.prop1 = 2;
a.prop2 = { prop3: 2 };
b.prop1 = 2;
b.prop2 = { prop3: 3 };
O objeto pode ser muito mais complexo com mais propriedades aninhadas. Mas este é um bom exemplo. Eu tenho a opção de usar funções recursivas ou algo com lodash ...
javascript
lodash
JLavoie
fonte
fonte
_.isEqual(value, other)
Executa uma comparação profunda entre dois valores para determinar se eles são equivalentes. lodash.com/docs#isEqualRespostas:
Uma solução fácil e elegante é usar
_.isEqual
, que realiza uma comparação profunda:No entanto, esta solução não mostra qual propriedade é diferente.
http://jsfiddle.net/bdkeyn0h/
fonte
_.isEqual
pode ser bem complicado. Se você copiar o objeto e alterar alguns valores, ele ainda será verdadeiro, porque a referência é a mesma. Portanto, é preciso ter cuidado ao usar esta função.Se você precisar saber quais propriedades são diferentes, use reduza () :
fonte
_.reduce(a, (result, value, key) => _.isEqual(value, b[key]) ? result : result.concat(key), [])
para uma solução ES6 de uma linhalet edited = _.reduce(a, function(result, value, key) { return _.isEqual(value, b[key]) ? result : result.concat( { [key]: value } ); }, []);
Para quem se deparar com esta discussão, aqui está uma solução mais completa. Ele comparará dois objetos e fornecerá a chave de todas as propriedades que estão apenas no objeto1 , apenas no objeto2 ou que estão no objeto1 e no objeto2, mas que possuem valores diferentes :
Aqui está um exemplo de saída:
Se você não se importa com objetos aninhados e deseja pular o lodash, pode substituir
_.isEqual
por uma comparação de valor normal, por exemploobj1[key] === obj2[key]
.fonte
Com base na resposta de Adam Boduch , escrevi esta função que compara dois objetos no sentido mais profundo possível , retornando caminhos que possuem valores diferentes e caminhos ausentes de um ou outro objeto.
O código não foi escrito com eficiência em mente, e as melhorias nesse sentido são bem-vindas, mas aqui está a forma básica:
Você pode tentar o código usando este trecho (é recomendável executar no modo de página inteira):
Mostrar snippet de código
fonte
b
usandob.hasOwnProperty(key)
oukey in b
nãob[key] != undefined
. Com a versão antiga usadab[key] != undefined
, a função retornou um diff incorreto para objetos que contenhamundefined
, como emcompare({disabled: undefined}, {disabled: undefined})
. De fato, a versão antiga também teve problemas comnull
; você pode evitar problemas como esse sempre usando===
e em!==
vez de==
e!=
.Aqui está uma solução concisa:
fonte
[]
.Para mostrar recursivamente como um objeto é diferente de outro, você pode usar _.reduce combinado com _.isEqual e _.isPlainObject . Nesse caso, você pode comparar como a é diferente com b ou como b é diferente com a:
fonte
_.isEqual
Método de uso simples , ele funcionará para todos ...Então, se você tem abaixo:
Se você fizer isso:
_.isEqual(firstName, otherName);
,retornará verdadeiro
E se
const fullName = {firstName: "Alireza", familyName: "Dezfoolian"};
Se você fizer isso:
_.isEqual(firstName, fullName);
,retornará falso
fonte
Este código retorna um objeto com todas as propriedades que possuem um valor diferente e também valores de ambos os objetos. Útil para registrar a diferença.
fonte
Sem o uso de lodash / underscore, escrevi esse código e está funcionando bem para uma comparação profunda de objeto1 com objeto2
fonte
Comparação profunda usando um modelo de propriedades (aninhadas) para verificar
Isso funcionará no console. Suporte de matriz pode ser adicionado se necessário
fonte
Peguei uma facada no código de Adam Boduch para produzir uma diff profunda - isso é totalmente não testado, mas as partes estão lá:
fonte
diff({}, { foo: 'lol', bar: { baz: true }}) // returns []
Como foi solicitado, aqui está uma função de comparação de objetos recursivos. E um pouco mais. Supondo que o uso primário dessa função seja a inspeção de objetos, tenho algo a dizer. A comparação profunda e completa é uma má idéia quando algumas diferenças são irrelevantes. Por exemplo, a comparação profunda cega nas afirmações de TDD torna os testes desnecessários frágeis. Por esse motivo, gostaria de apresentar uma diferença parcial muito mais valiosa . É um análogo recursivo de uma contribuição anterior a este segmento. Ele ignora as chaves não presentes em um
O BDiff permite verificar os valores esperados enquanto tolera outras propriedades, exatamente o que você deseja para a inspeção automática . Isso permite criar todos os tipos de asserções avançadas. Por exemplo:
Voltando à solução completa. Construir um diff tradicional completo com o bdiff é trivial:
A execução da função acima em dois objetos complexos produzirá algo semelhante a este:
Finalmente, para ter uma idéia de como os valores diferem, podemos avaliar diretamente () a saída do diff. Para isso, precisamos de uma versão mais feia do bdiff que produz caminhos sintaticamente corretos:
Isso produzirá algo semelhante a este:
Licença MIT;)
fonte
Completando a resposta de Adam Boduch, este leva em diferenças nas propriedades
fonte
Se você precisar apenas de comparação de chaves:
fonte
Aqui está um simples texto datilografado com o verificador de diferenças profundas Lodash que produzirá um novo objeto com apenas as diferenças entre um objeto antigo e um novo objeto.
Por exemplo, se tivéssemos:
o objeto resultante seria:
Também é compatível com objetos profundos de vários níveis; para matrizes, pode ser necessário algum ajuste.
fonte
fonte
===
diretamente,{ a: 20 } === { a: 20 }
retornará false, porque compara o protótipo. Forma mais direito de objetos comparar principalmente é envolvê-los emJSON.stringify()
_.isEqual(f, s)
? :)f
for um objeto e você conseguiráif (_.isObject(f))
simplesmente voltar à função e atingir esse ponto novamente. O mesmo vale paraf (Array.isArray(f)&&Array.isArray(s))
isso foi baseado em @JLavoie , usando lodash
https://jsfiddle.net/EmilianoBarboza/0g0sn3b9/8/
fonte
apenas usando baunilha js
fonte
Para aproveitar a resposta de Sridhar Gudimela , aqui ela é atualizada de uma maneira que fará o Flow feliz:
fonte