An Example (On Environment and Learning cont.)
mari tang
Posted on September 12, 2018
So I'm working through Eloquent Javascript, and I'm supposed to compose a function out of other functions. Fine. The concept does make sense to me, and I think I'm a pretty dedicated study.
But then I run into this:
function countBy(items, groupName) {
let counts = [];
for (let item of items) {
let name = groupName(item);
let known = counts.findIndex(c => c.name == name);
if (known == -1) {
counts.push({name, count: 1});
} else {
counts[known].count++;
}
}
return counts;
}
This is frustrating, so I'm writing this post mostly as a way of unblocking myself and walking through the process of building an understanding of code.
I can tell that it's a function called countBy, with parameters "items" and "groupName". I can tell that it initializes an empty array called "counts".
Where I start having trouble is the for/of loop. "item" isn't defined anywhere in the code, and I haven't been introduced to it anywhere else in the text.
Well, that's fine. We're supposed to know how to google stuff, right? I'll start with searing for "for of loop js".
That lands us at MDN. Great, now I can figure out how the loop works and be on my way!
Let's look at what's on the page:
The for...of statement creates a loop iterating over iterable objects, including: built-in String, Array, Array-like objects (e.g., arguments or NodeList), TypedArray, Map, Set, and user-defined iterables. It invokes a custom iteration hook with statements to be executed for the value of each distinct property of the object.
so the loop iterates over iterable objects. This begs a few questions:
- what do you mean by "iterates over"?
- what is an iterable object?
I'm guessing that the answer to question 1 is that it's similar to the way that we can access each item in an array by feeding it through this code:
for (let i = 0; i < array.length; i++){
array[i];
}
Okay, not bad so far. However, what I need are the specifics. I know how to get the current item out of an array, but where does this thing put the name of the thing we're iterating over? Where does it put the values associated with those names?
I'll look at the docs again to figure it out.
function* foo(){
yield 1;
yield 2;
}
for (let o of foo()) {
console.log(o);
// expected output: 1
break; // closes iterator, triggers return
}
Well, I can see (let o of foo()) and console.log(o), so it would seem to me that "o" is similar to the "i" in my earlier for loop. However, what does the "o" correspond to? is it the location/name or the value of whatever I'm looping through?
The expected output is 1. That seems to correspond to the first primitive value I see in the function. yield 1. But I don't know what "yield" actually does, so now I have to look that up. Luckily MDN has a page for that too.
The yield keyword is used to pause and resume a generator function (function* or legacy generator function).
Okay, what the fuck.
I don't know what a generator function is, or what a legacy generator function is.
Now my choices are to either dig into what a generator function is, or to pop back over to the for/of page and try to find a different example.
Let's do the latter, obviously. No need to keep digging myself deeper.
let iterable = [10, 20, 30];
for (let value of iterable) {
console.log(value);
}
// 10
// 20
// 30
Okay, that's much better. It looks like, in this for/of loop, we're not dealing with indexes or w/e. We just get the value of each item in the array via "value" during each loop. I'm pretty sure I can work with this.
But I do want to talk about one part of the way this documentation works. It's not explicitly stated that the bits that are commented out are what's expected to be logged to the console.
// 10
// 20
// 30
For me, that's not a problem. I've done enough JS that I guessed that that's probably what it was, and could test it myself in order to verify that I was correct, since I know how to use a js console/websites like replit that will give you a sandbox. However, if you had put me in front of this bit of documentation about a month ago, I might not have been able to intuit that bit of information, or known how to test it.
This is what I was talking about in my previous post. I don't know where you'd actually go as a total newbie in order to pick up that information, except to ask someone more experienced than you. There are a million little pain points like this, which feel completely arbitrary and unexpected as you're getting started. Simple things that could be solved in a matter of minutes if you knew where/who/how to ask, but can absolutely crush your momentum and motivation if you don't have that kind of access.
This is where "just google it" or "read the docs" is insufficient, or, if it is, it severely undersells the amount of time and effort it takes to google the answer to a problem, which can be discouraging.
What I find truly pleasurable about programming is a certain sense of consistency; given that you have an understanding of basic operations, you can logically build up any sort of functionality you need. It's the moments where this seems to fail, or to be blockaded by an arbitrary bit of knowledge or convention that I'm lacking that I'm most painfully frustrated by the process.
Now, after all of this, I still have to look up how the findIndex method works, and hope that my knowledge and skills are in the right place to be able to parse that documentation before I've spent all the focus I'm able to, and then I can finally do the work of actually figuring out how I'm going to feed countBy into or out of other functions (granted that I don't have to repeat this process too many times with the rest of the functions I'm trying to compose).
This is why I have bags under my eyes.
Posted on September 12, 2018
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.