[functional JS ES6+] generator와 iterator
작성:    
업데이트:
카테고리: Functional JS
태그: FE Language, Functional JS, JS
본 포스트는 인프런의 함수형 프로그래밍과 JavaScript ES6+ 강의(링크)를 듣고 정리한 내용입니다.
generator
- iterator이자, iterable을 생성(return)하는 함수
iter[Symbol.iterator]() == iter
, 즉 자기 자신을 return하는 well-formed iterator
function *gen() {
yield 1;
yield 2;
yield 3;
return 100;
}
let iter = gen();
log(iter.next()); // {value: 1, done: false}
log(iter.next()); // {value: 2, done: false}
log(iter.next()); // {value: 3, done: false}
log(iter.next()); // {value: return, done: true}
for (const a of gen()) log(a); // 1 \n 2 \n 3
- 일반 함수 앞에 ‘*’ 표시를 붙여 만든다.
- iterator이므로 next() method와 for of 문을 통한 순회도 가능
- yield로 각 단계를 표시하고, return값은 done: true에 나오는 값
yield는 문장도 가능
yield 1;
if (false) yield 2;
yield 3;
이는 곧 어떠한 값도 순회할 수 있는 객체로 만들 수 있다는 말
generator의 활용
홀수 generator: odds
홀수만 뽑는 generator odds를 만든다
function *adds(l) {
for (let i=0; i<l; i++) {
if (i % 2) yield i;
}
}
let iter2 = odds(10);
log(iter2.next()); // {value: 1, done: false}
log(iter2.next()); // {value: 3, done: false}
log(iter2.next()); // {value: 5, done: false}
log(iter2.next()); // {value: 7, done: false}
log(iter2.next()); // {value: 9, done: false}
log(iter2.next()); // {value: undefined, done: true}
log(iter2.next()); // {value: undefined, done: true}
무한수열 generator: infinity
function *infinity(i = 0) {
while (true) yield i++;
}
let iter3 = infinity();
iter3.next(); // {value: 1, done: false}
iter3.next(); // {value: 2, done: false}
iter3.next(); // {value: 3, done: false}
iter3.next(); // {value: 4, done: false}
- iterator의 next를 평가할 때까지만 동작하므로 while문에 따른 오류는 없다.
여러 generator의 결합
function *infinity(i = 0) {
while (true) yield i++;
}
function *odds(l) {
for (const a of infinity(1)) {
if (a % 2) yield a;
if (a == l) return;
}
}
let iter2 = odds(10);
log(iter2.next()); // {value: 1, done: false}
log(iter2.next()); // {value: 3, done: false}
...
log(iter2.next()); // {value: 9, done: false}
log(iter2.next()); // {value: undefined, done: true}
/////////////////////////////////////////////////////////////////
function *limit(l, iter) {
for (const a of iter) {
yield a;
if (a == l) return;
}
}
let iter4 = limit(4, [1, 2, 3, 4, 5, 6]);
log(iter4.next()); // {value: 1, done: false}
log(iter4.next()); // {value: 2, done: false}
log(iter4.next()); // {value: 3, done: false}
log(iter4.next()); // {value: 4, done: false}
log(iter4.next()); // {value: undefined, done: true}
댓글남기기