Open panzerdp opened 4 years ago
Comment written by Alon Valadji on 06/09/2020 21:59:28
JSON.stringify(object1) === JSON.stringify(object2)
won't work with circular objects.
However, you can use JSON.stringify
replace function to hash the circular object and gain a full deep comparison.
see how cycle.js does it:
https://github.com/douglasc...
TypeError: cyclic object value on MDN:
https://developer.mozilla.o...
Comment written by Dmitri Pavlutin on 06/10/2020 06:55:47
Good to know. Thanks for sharing @alonronin:disqus.
Comment written by Federico Kereki on 06/12/2020 17:39:25
Another problem with JSON.stringify:
obj1 = {a:2, b:4};
obj2 = {b:4, a:2};
JSON.stringify(obj1); // "{"a":2,"b":4}"
JSON.stringify(obj2); // "{"b":4,"a":2}"
Comment written by veganaiZe on 06/12/2020 22:06:11
JSON.stringify()
doesn't include methods.
Comment written by Dmitri Pavlutin on 06/13/2020 09:20:15
Exactly. JSON.stringify preserves properties order, which makes it error-prone to compare objects.
Comment written by Nicholas Tapia on 06/13/2020 17:26:10
I love reading about your reasoning and thought process. I really helps me as a novice programmer to understand! Two questions:
1) You recommend:
isDeepStrictEqual(object1, object2) or _.isEqual(object1, object2)
Why do you recommend them?
2) What are some real world examples of when one would need to do referential equality on objects?
Comment written by Dmitri Pavlutin on 06/13/2020 18:13:34
Hi @disqus_vqzZeHeESm:disqus ,
1) Why do you recommend them?
If you're writing a Node application, it's better to use the built-in Node modules/functions. This way you don't have to write the functions by yourself, or add another dependency if you choose to use a utility library from npm.
2) What are some real world examples of when one would need to do referential equality on objects?
For example, if you'd like to store some information related to an object, but not on the object itself. You could store the data into an array having tuples of object and related data: [[object1, relatedData2], [object2, relatedData2], ...]. Then to access the related data of an object, you could iterate the array and use the object referential equality to find the match.
Comment written by Nicholas Tapia on 06/13/2020 23:26:54
Very helpful! Thank you kindly!
Comment written by Rayan Noe on 06/15/2020 11:38:54
use
```
const propertyName = keys1[index];
const val1 = object1[propertyName];
const val2 = object2[propertyName];
```
instead
```
const val1 = object1[keys1[index]];
const val2 = object2[keys2[index]];
```
otherwise it will return true if the property name is different in same position and value is equal.
eg :
deepEqual({ "name1" : "abc" } , { "name2" : "abc" });
Comment written by Dmitri Pavlutin on 06/15/2020 12:14:52
You're right. I will fix the functions.
Comment written by jay on 07/21/2020 03:55:06
JSON.stringify is fine for smaller objects. There is still a limitation for the size of string that can be compared in JavaScript.
Comment written by Дмитрий on 09/17/2020 04:33:50
Thnx, Dima, so clear!
const hero1 = {
name: 'Batman',
realName: 'Bruce Wayne'
};
const hero2 = {
name: 'Batman',
realName: 'Bruce Wayne'
};
const hero3 = {
name: 'Joker'
};
function cpObj(obj1,obj2){
const tmp = {...obj1,...obj2}
return JSON.stringify(obj1) === JSON.stringify(tmp)
}
cpObj(hero1,hero2)
Hi Dima. Great job. small improvs - if I may - to use this function to all sort of objects. Here is my function code. I has many recursive calls...
export const objectsCompare = (obj1,obj2) => { const primitive = ['string','number','boolean','undefined']; const typeA = typeof obj1; const typeB = typeof obj2; if (typeA!==typeB) {return false}; if (primitive.includes(typeA)) {return obj1===obj2} //if got here - objects if (obj1.length!==obj2.length) {return false} //check if arrays const isArrayA = Array.isArray(obj1); const isArrayB = Array.isArray(obj2); if (isArrayA !== isArrayB) {return false} if (isArrayA) { //arrays for (let i = 0; i < obj1.length; i++) { if (!objectsCompare(obj1[i],obj2[i])) {return false} } } else { //objects //compare object keys if (!objectsCompare(Object.keys(obj1).sort(),Object.keys(obj2).sort())) {return false} //compare object values let result=true; Object.keys(obj1).forEach((key)=>{ if (!objectsCompare(obj1[key],obj2[key])) {result=false} }) return result } return true }
Hi Dima. Great job. small improvs - if I may - to use this function to all sort of objects. Here is my function code. I has many recursive calls...
Thanks for sharing your implementation @talHaram.
Great blog starting from the content ending with the text structure, fonts and design.
A better shallow comp!
function shallowEqual(object1, object2) {
const keys1 = Object.keys(object1);
const keys2 = Object.keys(object2);
// cannot simply compare key-array lengths as lengths could be same while the keys themselves differ
// cannot skip this check either and just check the values of all keys concatenated
// because { "key": undefined }["key"] and {}["key"] would equal incorrectly
for (const k of keys1) if (!keys2.includes(k)) return false;
for (const k of keys2) if (!keys1.includes(k)) return false;
for (const key of keys1) if (object1[key] !== object2[key]) return false;
return true;
}
thx :)
Great overview. thank you for nice, clean and short explanation. Enjoyed!
Great overview. thank you for nice, clean and short explanation. Enjoyed!
Glad you like it @nzolotar!
Written on 06/07/2020 14:05:08
URL: https://dmitripavlutin.com/how-to-compare-objects-in-javascript/