I’m trying to understand the advanced code solution for the Intermediate Algorithm Scripting: Wherefore art thou challenge, but I’m having some trouble, particularly with regards to the reduce and obj[key] === source[key] parts.
I tried using console.log (like console.log(obj[key]), but nothing is showing up even though this worked when I tried to console.log sourceKeys.
I wrote down the advanced code solution shown in the guide using arrow functions:
let whatIsInAName = (collection, source) => {
let sourceKeys = Object.keys(source);
return collection.filter(obj => sourceKeys.map(key => obj.hasOwnProperty(key) && obj[key] === source[key]).reduce((prev, curr) => prev && curr));
};
console.log(whatIsInAName([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" }));
Then I tried to explain each piece of code:
First, use Object.keys to get the name/s of the objects in the source parameter and store the value in a variable. In this case, when you console.log sourceKeys, you get [“last”].
Next, use filter on the array of objects in the collection parameter. Filter will loop or iterate through each of these objects. The functions inside filter will then be applied to each of these objects. Filter will return a new array. This new array will be made up of the objects that pass the functions implemented by filter.
Inside filter, use map on sourceKeys. Map will loop or iterate through each of the elements or values in the sourceKeys array. Each time map runs, check if any of the objects in collection (obj) have the same value as in any of the property names in sourceKeys (key) - this corresponds to the obj.hasOwnProperty(key).
In this case, we’re checking if any of the objects in collection have a “last” property. If yes, hasOwnProperty will return true. Otherwise, it will return false. In the example given, there are 3 objects in the collection parameter:
{ first: "Romeo", last: "Montague" }
{ first: "Mercutio", last: null }
{ first: "Tybalt", last: "Capulet" }
All of them have the “last” property, so hasOwnProperty will return true for all 3.
Is this right so far?
After that is where things get confusing for me. I’m not sure exactly what this code
obj[key] === source[key]
corresponds to. Using console.log doesn’t show me anything. Are we checking if the value of “last” in the object parameter is the same as the value of “last” in the source parameter?
So we’re looking to see which item in collection has this object: { last: “Capulet” }. Is that correct? But then I thought key was referring to just “last”. Does key also refer to the value of “last”? So, does it go like this:
{ first: "Romeo", last: "Montague" } === { last: "Capulet" }
The answer is false
{ first: "Mercutio", last: null } === { last: "Capulet" }
The answer is false
{ first: "Tybalt", last: "Capulet" } === { last: "Capulet" }
The answer is true
Is that right? Then after that, use the logical AND operator to compare the Boolean value we got above from the Boolean value we got from hasOwnProperty. The logical AND (&&) operator will only return true if both sides of the argument are true. If even one side of the argument turns out to be false, the whole thing will return false.
true && false = false
true && false = false
true && true = true
So map will return this array: [false, false, true]. Is this correct? Then we use reduce on this array, so we only get a single Boolean value. prev refers to the previous value in the array while curr refers to the current value in the array. We use the logical AND operator to compare the previous and current values. Since there’s no initial value, we start by comparing the first two values, right? So, that would be:
false && false = false
Then the value we got above becomes the new prev while the next value in the array becomes the new curr, right? So, we’ll get:
false && true = false
Is this correct? Am I supposed to be getting false here? This is also another part where I got confused as I’m not sure how the filter comes into play here.
I know filter is supposed to be filtering out the false values, returning a new array with only the elements that returned true, but I’m confused how this works here. If we end up with false, wouldn’t this be filtered out or removed from the array returned by filter?
Can anyone clarify what’s going on here? How does this code work?