J'ai 2 objets imbriqués qui sont différents et j'ai besoin de savoir s'ils ont des différences dans l'une de leurs propriétés imbriquées.
var a = {};
var b = {};
a.prop1 = 2;
a.prop2 = { prop3: 2 };
b.prop1 = 2;
b.prop2 = { prop3: 3 };
L'objet pourrait être beaucoup plus complexe avec plus de propriétés imbriquées. Mais celui-ci est un bon exemple. J'ai la possibilité d'utiliser des fonctions récursives ou quelque chose avec lodash ...
javascript
lodash
JLavoie
la source
la source
_.isEqual(value, other)
Effectue une comparaison approfondie entre deux valeurs pour déterminer si elles sont équivalentes. lodash.com/docs#isEqualRéponses:
Une solution simple et élégante est à utiliser
_.isEqual
, qui effectue une comparaison approfondie:Cependant, cette solution ne montre pas quelle propriété est différente.
http://jsfiddle.net/bdkeyn0h/
la source
_.isEqual
peut être assez délicat. Si vous copiez l'objet et modifiez certaines valeurs à l'intérieur, il restera vrai, car la référence est la même. Il faut donc être prudent en utilisant cette fonction.Si vous avez besoin de savoir quelles propriétés sont différentes, utilisez réduire () :
la source
_.reduce(a, (result, value, key) => _.isEqual(value, b[key]) ? result : result.concat(key), [])
pour une solution ES6 à une lignelet edited = _.reduce(a, function(result, value, key) { return _.isEqual(value, b[key]) ? result : result.concat( { [key]: value } ); }, []);
Pour toute personne tombant sur ce fil, voici une solution plus complète. Il comparera deux objets et vous donnera la clé de toutes les propriétés qui sont soit uniquement dans object1 , uniquement dans object2 , soit dans object1 et object2 mais qui ont des valeurs différentes :
Voici un exemple de sortie:
Si vous ne vous souciez pas des objets imbriqués et que vous souhaitez ignorer lodash, vous pouvez remplacer le par
_.isEqual
pour une comparaison de valeurs normales, par exempleobj1[key] === obj2[key]
.la source
Sur la base de la réponse d'Adam Boduch , j'ai écrit cette fonction qui compare deux objets dans le sens le plus profond possible , renvoyant des chemins qui ont des valeurs différentes ainsi que des chemins manquants dans l'un ou l'autre objet.
Le code n'a pas été écrit dans un souci d'efficacité et les améliorations à cet égard sont les bienvenues, mais voici la forme de base:
Vous pouvez essayer le code à l'aide de cet extrait (il est recommandé de l'exécuter en mode pleine page):
Afficher l'extrait de code
la source
b
utilisantb.hasOwnProperty(key)
oukey in b
pas avecb[key] != undefined
. Avec l'ancienne version utiliséeb[key] != undefined
, la fonction a renvoyé un diff incorrect pour les objets contenantundefined
, comme danscompare({disabled: undefined}, {disabled: undefined})
. En fait, l'ancienne version avait également des problèmes avecnull
; vous pouvez éviter de tels problèmes en utilisant toujours===
et!==
au lieu de==
et!=
.Voici une solution concise:
la source
[]
.Pour montrer récursivement comment un objet est différent des autres, vous pouvez utiliser _.reduce combiné avec _.isEqual et _.isPlainObject . Dans ce cas, vous pouvez comparer en quoi a est différent de b ou en quoi b est différent de a:
la source
_.isEqual
Méthode d' utilisation simple, elle fonctionnera pour tous en comparant ...Donc, si vous avez ci-dessous:
Si vous le faites:
_.isEqual(firstName, otherName);
,ça reviendra vrai
Et si
const fullName = {firstName: "Alireza", familyName: "Dezfoolian"};
Si vous le faites:
_.isEqual(firstName, fullName);
,retournera faux
la source
Ce code renvoie un objet avec toutes les propriétés qui ont une valeur différente ainsi que les valeurs des deux objets. Utile pour enregistrer la différence.
la source
Sans utilisation de lodash / underscore, j'ai écrit ce code et fonctionne très bien pour moi pour une comparaison approfondie de object1 avec object2
la source
Comparaison approfondie à l'aide d'un modèle de propriétés (imbriquées) pour vérifier
Cela fonctionnera dans la console. La prise en charge des baies peut être ajoutée si nécessaire
la source
J'ai essayé un code d'Adam Boduch pour produire un diff profond - ce n'est pas encore testé mais les morceaux sont là:
la source
diff({}, { foo: 'lol', bar: { baz: true }}) // returns []
Comme il a été demandé, voici une fonction de comparaison d'objets récursive. Et un peu plus. En supposant que l'utilisation principale d'une telle fonction est l'inspection d'objets, j'ai quelque chose à dire. Une comparaison approfondie complète est une mauvaise idée lorsque certaines différences ne sont pas pertinentes. Par exemple, une comparaison approfondie aveugle dans les assertions TDD rend les tests inutiles fragiles. Pour cette raison, je voudrais introduire un diff partiel beaucoup plus précieux . Il s'agit d'un analogue récursif d'une contribution précédente à ce fil. Il ignore les clés non présentes dans un
BDiff permet de vérifier les valeurs attendues tout en tolérant d'autres propriétés, ce qui est exactement ce que vous souhaitez pour une inspection automatique . Cela permet de construire toutes sortes d'assertions avancées. Par exemple:
Revenons à la solution complète. Construire un diff traditionnel complet avec bdiff est trivial:
L'exécution de la fonction ci-dessus sur deux objets complexes produira quelque chose de similaire à ceci:
Enfin, afin d'avoir un aperçu de la façon dont les valeurs diffèrent, nous pouvons vouloir évaluer directement () la sortie diff. Pour cela, nous avons besoin d'une version plus laide de bdiff qui génère des chemins syntaxiquement corrects:
Cela produira quelque chose de similaire à ceci:
Licence MIT;)
la source
Complétant la réponse d'Adam Boduch, celui-ci prend en compte les différences de propriétés
la source
Si vous n'avez besoin que d'une comparaison clé:
la source
Voici un simple tapuscrit avec vérificateur de différence profonde Lodash qui produira un nouvel objet avec juste les différences entre un ancien objet et un nouvel objet.
Par exemple, si nous avions:
l'objet résultant serait:
Il est également compatible avec les objets profonds à plusieurs niveaux, pour les tableaux, il peut nécessiter quelques ajustements.
la source
la source
===
directement des objets avec ,{ a: 20 } === { a: 20 }
retournera false, car il compare le prototype. La meilleure façon de comparer principalement des objets est de les envelopperJSON.stringify()
_.isEqual(f, s)
? :)f
est un objet et que vous y arrivez,if (_.isObject(f))
revenez simplement sur la fonction et touchez à nouveau ce point. Il en va de mêmef (Array.isArray(f)&&Array.isArray(s))
cela était basé sur @JLavoie , en utilisant lodash
https://jsfiddle.net/EmilianoBarboza/0g0sn3b9/8/
la source
juste en utilisant vanille js
la source
Pour s'appuyer sur la réponse de Sridhar Gudimela , ici, elle est mise à jour d'une manière qui rendra Flow heureux:
la source