Transcript from the "Creating a Custom Iterator" Lesson
>> Kyle Simpson: All right our final topic for us to pay attention to is, how do we make our own iterators? What if I have a value, an object or something that I've created, and I'd like for it to be consumable through any of those various Iterable Consumptions that we just talked about like dot, dot, dots or four eye loops or whatever, it's a standard interface but how do I make myself an iterator.
[00:00:28] I mean there's the manual crappy way which I'm going to show you first and then there's a much nicer way using what we call generators, okay. So, let's look at the old crappy way first. Let's say I wanted to make an object like this. And, I don't know, let's say that it had like a limit on it of 13.
[00:00:47] And what I wanted to do is make, let's do this.
>> Kyle Simpson: Right, let's just say it had those properties on it. And what I wanted to do is I wanted to make it so that object was iterable in that, what it would do is go through a list of values.
[00:01:15] Like this.
>> Kyle Simpson: Going to do this 2, 4, 6
>> Kyle Simpson: Yeah, I think I have enough now. Okay. So, let's say that we have, it has a values array but also these properties on it starting in. And what I'd like to do is I'd like to make object iterable, meaning that it would automatically Loop through the values in the values or in its own values starting at start position and ending at end village.
[00:01:54] That's my custom iteration that I want to be able to make available to people. So, how do I make my object into an interval? What I want to do is I wanna add a function at that special symbol dot iterator location Using the computed property syntax, I'm gonna say symbol.iterator and I need to make a function here.
[00:02:14] So, I could do the old function syntax but now remember that we can do concise methods. So, I'm gonna make it a concise method. Let's think about what this thing needs to do. This thing needs to construct an iterator. What is an iterator? It is an object that has a dot next method on it right.
[00:02:41] We're going to make an iterator so I'm gonna do that super manually. We're gonna make an iterator, and we're gonna return it. Are you with me?
>> Kyle Simpson: That iterator needs to have a method on it called next.
>> Kyle Simpson: With me so far?
>> Kyle Simpson: Now, when we construct this iterator instance, what we wanna do Is capture the current state of this .start.
[00:03:12] And this .end. Because we don't want those to change out from underneath us. Okay. I'm also going to keep track of where I currently am. So, I'm going to start my index at start. You're with me?
>> Kyle Simpson: As a matter of fact, we don't even need to really keep track of start, we can just say index there.
>> Kyle Simpson: So, we're gonna index starting at start. We need to keep track of index and where we're ending.
>> Kyle Simpson: And probably already guess where I'm going with this, but what we're gonna do every time the dock next method is called. We want to get out the current value in the values array at the position, that index represents.
[00:04:01] Okay. So, we wanna say.
>> Kyle Simpson: V is equal to, now here, we have a question of what object are we looking at. We could say object of index but this is not a variable name that we wanna use is it, that's bad. So, the thing that we really wanna use is of this But now we're inside of a function which isn't gonna be pointing at that this.
[00:04:30] So, this is maybe one of those cases where an arrow function might be a little bit helpful. So, how about if we go and make the next into an arrow function, okay only so that, we don't want to mess around with this bindings. Where is it gonna get it's this binding from?
[00:04:49] From the outer function whose this keyword is obj. You with me? All right, so now I"ve got a next arrow function here. It grabs the current value of this[idx], it increments index because we're gonna Probably call it the next time. So, it's going to increment index. And then it's going to need to say return.
[00:05:16] An object that has a value of v and a done we have to figure out if we want to return true or false. So, we could say that done needs to be true, If index is greater than the end value that we wanted to be at it. You with me?
[00:05:47] Now, furthermore we might wanna say we wanna guard this value we don't wanna send out a value if done is going to be true. So, we could kinda work this logic slightly differently we could say if index is less than or equal to en, let's do this stuff And then we just know done falls.
[00:06:10] Otherwise, indexes already above en, which means we don't want to do anything else we want to signal that the iteration is done so we're gonna just return done true, we don't even need to include value because it's going to imply. Value undefined. Did you follow that kind of crazy logic that I went through?
[00:06:34] Now, I fully recognize this sucks. Nobody wants to write this code but I'm just setting you up for how much easier this going to be in just a moment okay? When we use generators. The ugly crappy way of doing this we got to make our own custom iterator using These techniques.
[00:06:51] Let's test ourselves, let's see we should be able to say. Give me the vals and we should be able to say dot dot dot OBJ. Even though it's an object it now has an interator, so it ought to be able to be iterated with dot dot dot. And vals ought to give us let's just check the 0, 1, 2, 3, 4 it ought to give us 10, 1, 2, 3, 4, 5, 6, 7, 8,
>> Kyle Simpson: Oops 0, 1
>> Kyle Simpson: Let me add some more on just to make sure. We ought to get, 10 through 28, if I'm not doing my math wrong okay? So let's just see, see if I didn't make a mistake.
>> Kyle Simpson: Oops I messed up, let's see here.
>> Kyle Simpson: Did I do that yet?
[00:08:04] Get of the.
>> Speaker 2: Shouldn't be this at line 8? Shouldn't that be this that values to idx?
>> Kyle Simpson: You're absolutely right, thank you.
>> Kyle Simpson: Good catch. Hey, our programming works.
>> Kyle Simpson: There we go, 10 through 28, okay. So, we made our object a custom iterator and it did the logic we were hoping for.
[00:08:44] You notice that it automatically knew when to stop because we returned a done true. And knew where to start and knew where to stop.