(see the screenshots) I’m comparing two identical objects in 2 cases, but ones return true and another false. I though it was because in spite of the same properties and value pairs each pair is allocated in different memory spaces, but from my point of view that doesn’t explain why the other function is returning true.
Why am I getting different results using the same approach?
function whatIsInAName(collection, source) {
// What's in a name?
var arr = [];
// Only change code below this line
arr = collection.filter(objInArr =>
objInArr.hasOwnProperty(Object.keys(source)))
// Only change code above this line
return arr;
}
console.log(whatIsInAName([{ "apple": 1 }, { "apple": 1 }, { "apple": 1, "bat": 2 }], { "apple": 1 }))
Your browser information:
User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36 OPR/66.0.3515.72.
Comparing two object in Javascript is a bit problematic.
A true deep comparison is not so easy to achieve, for a reference look at how lodash implements _isEqual()
This is partially due to the fact that for each new object JS allocate a new memory “space”.
This means that for JS two “ponters” to an object are identical if they refer to the same memory address.
Example
let x = {
"foo": "bar"
}
let y = {
"foo": "bar"
}
let z = {...x};
let j = x;
x === y // false
x === z // false
x === j // true
Given this premise, your ways to compare two object is not sufficient for a true “deep” comparison.
Your function is looking if for each key in source, there’s a key in objInArray
objInArr.hasOwnProperty(Object.keys(source))
This has the flaw, like in your example that to output a positive outcome source needs to have the same keys, but it’s not true the other way around:
Consider this example:
let a = {
"foo": "bar",
"extra": "props",
"cool": true,
}
let b = {
"foo": "bar"
}
a.hasOwnProperty(Object.keys(b)) // true
This will produce true since a has all the keys of b; but not the other way around.
Thank you Dan!.
Wouldn’t be a solution to iterate on each possible key in source and extract each one to use it as an argument into hasOwnProperty (which should iterate on collection as much as number of keys source has)?
Yep, that would definitely work. You can use every to iterate over and return true if hasOwnProperty is true for every one.
Note that while that fulfils one of the conditions (keys are the same), it doesn’t fulfil the second (values as well). Look at Object.entries to get keys and values, you maybe won’t need hasOwnProperty when you use this (I’ll leave it to you to try out things though)