I think the code got a bit more complicated than it needed to for the Array case, so here's the slightly simplified code on github: github.com/neetcode-gh/leetcode/blob/main/javascript/2628-json-deep-equal.js
Basically we can reduce type comparisons to the following types- Primitive types object array NULL We can create a small helper method to distinguish object / array / null. This would make the problem easier and more readable. TypeScript code- function areDeeplyEqual(o1: any, o2: any): boolean { const type1 = getType(o1); const type2 = getType(o2); //First check. Check if base types are equal if(type1 !== type2){ return false; } // Check for equality of objects else if (type1 === 'object') { const keys1 = Object.keys(o1); const keys2 = Object.keys(o2); if (keys1.length !== keys2.length) { return false } for (let key of keys1) { /* Check is necessary to continue execution for remaining keys. */ if(!areDeeplyEqual(o1[key], o2[key])){ return false; } } } // Check for equality of arrays else if(type1 === 'array'){ const n1: number = o1.length; const n2: number = o2.length; if(n1 !== n2){ return false; } for(let i = 0; i < n1; i ++){ if(!areDeeplyEqual(o1[i], o2[i])){ return false; } } } // Check for primitives else { if (o1 !== o2) { return false; } } return true; }; //A utility to simplify type checking for arrays and null function getType(obj: any){ if(obj === null){ return 'NULL'; } else if(Array.isArray(obj)){ return 'array'; } return typeof obj; }
Why is 7:30 considered weird JS behavior? If we're trying to access a key on an object that doesn't exist, it seems very intuitive to me that it returns undefined. So if we compare that with an array that has undefined as it's value, then it makes perfect sense to me that it returns true. Am I missing something here?
The primitive value `undefined` should not be the same as something that doesn't exist. Other languages would throw keyerror or return a default value based on its type when accessing a key that doesn't exist in a hash table. JS basically set the default value to `undefined` so we have this problem of not knowing if it's the case that the key doesn't exist or if it's the case that the key exists and it's mapped to the value `undefined`. This is why it's weird. JS can't have a good default value and chooses `undefined` because it doesn't know what type it should be when the key doesn't exist. Python, also dynamically typed as JS, handles this better and it throws a KeyError exception in this case while also give you the option to specify a type and have a default value using `defaultdict(type)`.
I think the code got a bit more complicated than it needed to for the Array case, so here's the slightly simplified code on github: github.com/neetcode-gh/leetcode/blob/main/javascript/2628-json-deep-equal.js
Wouldn't say it is compilcated, for me it is more readable 😀 thanks for the video!
could please also post solutions for leetcode contest problems, especially last 2. Because your explanation is the best.
Yes this code was like doing much more work. Great the way Great content
This question is one of the better ones in this series as we're learning about types and type comparison in JS. Thanks
Basically we can reduce type comparisons to the following types-
Primitive types
object
array
NULL
We can create a small helper method to distinguish object / array / null. This would make the problem easier and more readable.
TypeScript code-
function areDeeplyEqual(o1: any, o2: any): boolean {
const type1 = getType(o1);
const type2 = getType(o2);
//First check. Check if base types are equal
if(type1 !== type2){
return false;
}
// Check for equality of objects
else if (type1 === 'object') {
const keys1 = Object.keys(o1);
const keys2 = Object.keys(o2);
if (keys1.length !== keys2.length) {
return false
}
for (let key of keys1) {
/*
Check is necessary to continue execution
for remaining keys.
*/
if(!areDeeplyEqual(o1[key], o2[key])){
return false;
}
}
}
// Check for equality of arrays
else if(type1 === 'array'){
const n1: number = o1.length;
const n2: number = o2.length;
if(n1 !== n2){
return false;
}
for(let i = 0; i < n1; i ++){
if(!areDeeplyEqual(o1[i], o2[i])){
return false;
}
}
}
// Check for primitives
else {
if (o1 !== o2) {
return false;
}
}
return true;
};
//A utility to simplify type checking for arrays and null
function getType(obj: any){
if(obj === null){
return 'NULL';
}
else if(Array.isArray(obj)){
return 'array';
}
return typeof obj;
}
Finally some classic DSA.
Thank you!
U should use the && operator to simplify some of the nested if statements.
Why is 7:30 considered weird JS behavior? If we're trying to access a key on an object that doesn't exist, it seems very intuitive to me that it returns undefined. So if we compare that with an array that has undefined as it's value, then it makes perfect sense to me that it returns true. Am I missing something here?
The primitive value `undefined` should not be the same as something that doesn't exist. Other languages would throw keyerror or return a default value based on its type when accessing a key that doesn't exist in a hash table. JS basically set the default value to `undefined` so we have this problem of not knowing if it's the case that the key doesn't exist or if it's the case that the key exists and it's mapped to the value `undefined`. This is why it's weird.
JS can't have a good default value and chooses `undefined` because it doesn't know what type it should be when the key doesn't exist. Python, also dynamically typed as JS, handles this better and it throws a KeyError exception in this case while also give you the option to specify a type and have a default value using `defaultdict(type)`.
Thanks for the daily
thanks
Day 17 of doing the 30-day challenge with neetcode!!
you talk way too fast in these videos. not helpful at all.