So, first thing’s first – my doctor’s proclaimed me healthy! Apparently the only thing I’ve been suffering from is paranoia stemming from me googling my own symptoms. So phew for that. (Although I am going in for an abdomen ultrasound for peace of mind this Friday).
Chapter 5: Higher-Order Functions
Brain gains made today
- Gained much more confidence dealing with the common array method functions
- .map is exactly like .forEach, except .map is not destructive (so it doesn’t mutate/change the original array).
- .filter accepts a callback function that has one purpose – to perform a test which will return either a true or false value. Remember also, .filter goes through each element of an array, and during each ‘loop’ it is using that test/Boolean value to determine whether to add the current element to the new array that it’s creating.
- .reduce is kind of like .forEach or .forMap. It accepts a callback function, but also another argument (let’s call it “initialValue”). As for the callback function itself, it accepts four arguments, and the special one is the first one, which I call “previousValue” (thanks MDN). Think of it like an accumulator argument: during each ‘loop’ executed by .reduce’s internal/abstracted logic, .reduce is going through an element of the array and performing an operation on it (just like .forEach and .map do). However, after each loop, .reduce’s internal logic adds whatever values/result returns from the loop (or ‘callback function invocation’ as they say) to ‘previousValue’, and this new version or value of ‘previousValue’ is used in the next version of the loop. The final thing .reduce’s internal logic does does is return the final result of the callback function/loop. And that’s it purpose – to return that final result, whatever it may be (depending on what you coded the callback function to do/pass to previousValue).
Biggest non-coder think problems
- I’ve discovered I need to do more exercises involving calling/using objects, object properties, object values and arrays of objects. Sometimes, it can be very difficult to ‘think’ through how to call a particular array-of-object’s property value, especially when you have to use something like the byName object in the exercise (and think through that lens of an object) whilst keeping track of the variable names. It was definitely headache inducing stuff, for a non-coder turned coder, but I have high hopes that exposure and familiarity will extinguish any future migraines.
- Method chaining: although my partial final answer didn’t let me apply this in the end (because I was breaking everything up into new arrays and separate functions), I did have the end goal of method chaining filter and map, so I think practice with this on my own will help me more comfortable in applying this correctly (for example, right now I believe it operates left to right, but again, something to double check)
- In the end, my solution was actually extremely close. The biggest let down? I’d figured out after doing an initial solution, that my .filter callback function was catching objects where the person’s mother also had their own object somewhere. What it wasn’t catching was instances where a person (and therefore their whole object) was a mother to another person in the array. So the great grandmothers with no further mothers were being culled… and I needed them so I could use their born/died year data to calculate the age differences between them and their children. I (stupidly) tried to solve this using another function and an or || operator but ultimately got stuck on this point. After substantial hair-pulling, when I checked the solution, I found I’d only been missing 6 freaking characters:
return byName[person.mother] != null;
*Note to self: learn to intuitively think/apply comparison operators, particularly for IF and .filter type tests (where Boolean values are required). Practice as much as required, because this kind of elegance beats whatever the hell else you just tried to do.