Search
Duplicate

제너레이터와 이터레이터

제너레이터와 이터레이터

제너레이터 이터레이터이자 이터러블을 생성및 반환하는 함수
function *gen(){ // * 을 붙히면 제너레이터가 된다. yield 1; yield 2; yield 3; } let iter = gen(); log(iter[Symbol.iterator]()==iter) // true log(iter.next()); // {value: 1, done: false} for(const a of gen()) log(a) // 1,2,3
JavaScript
복사
제너레이터는 순회 할 값을 문장으로 표현하는 것이라고 할 수 있다.
function *gen(){ yield 1; if(false) yield 2; yield 3; }
JavaScript
복사
제너레이터는 위와 같은 문장을 값으로 만들 수 있고, 이 문장을 통해 순회할 수 있는 값을 만들 수 있다. 이 말은 어떠한 값이나 상태든 순회할 수 있다는 의미.
즉, 어떠한 값도 순회할 수 있도록 조작할 수 있다는 말이 된다.

odds

이용하여 홀수만 반환하여 순회하는 제너레이터 만들어보기

직접 입력을 해야만 계속 홀수를 생성하는 제너레이터
function *odds(){ yield 1; yield 3; yield 5; } let iter2 = odds(); log(iter2.next()); //1 log(iter2.next()); //3 log(iter2.next()); //5
JavaScript
복사
홀수 생성을 자동화 한 제너레이터
function *odds(l){ for(let i = 0; i < l; i++){ if(i%2) yield i; } } let iter2 = odds(10); log(iter2.next()); //1 log(iter2.next()); //3 log(iter2.next()); //5 log(iter2.next()); //7 log(iter2.next()); //9 log(iter2.next()); //undefined
JavaScript
복사
무한 수열 제너레이터
function *infinity(i = 0){ while(true) yield i++; } let iter3 = infinity(); log(iter3.next()); //{value: 0, done: false} log(iter3.next()); //{value: 1, done: false} ... log(iter3.next()); //{value: n, done: false}
JavaScript
복사
제한(limit) 제너레이터
function *limit(l, iter){ for(const a of iter){ yield a; if(a == l) return; } } let iter4 = limit(3, [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: undefined, done: true} log(iter4.next()) //{value: undefined, done: true}
JavaScript
복사
홀수생성 제너레이터 응용
function *infinity(i = 0){ while(true) yield i++; } function *limit(l, iter){ for(const a of iter){ yield a; if(a == l) return; } } function * odds(l){ for(const a of limit(l, infinity(1))){ if(a % 2) yield a; } } let iter2 = odds(10); console.log(iter2.next());//{value: 1, done: false} console.log(iter2.next());//{value: 3, done: false} console.log(iter2.next());//{value: 5, done: false} console.log(iter2.next());//{value: 7, done: false} console.log(iter2.next());//{value: 9, done: false} console.log(iter2.next());//{value: undefined, done: true} console.log(iter2.next());//{value: undefined, done: true} for(const a of odds(40)) log(a) // 1,3,5,...39
JavaScript
복사

for...of, 전개연산자, 구조 분해, 나머지 연산자

모두 이터러블 프로토콜을 따르고 있는 함수들이다.
사례1 전개연산자와 제너레이터 사용
log(...odds(10)); // 1, 3, 5, 7, 9 log([...odds(10), ...odds(20)]); // [1,3,5,7,9,1,3,5,7,9,11,13,15,17,19]
JavaScript
복사
사례2 구조분해와 제너레이터 사용
const [head, ...tail] = odds(5); log(head); // 1 log(tail); //[3,5]
JavaScript
복사
사례3 나머지 연산자와 제너레이터 사용
const [a, b, ...rest] = odds(10); log(a); // 1 log(b); // 3 log(rest);//[5, 7, 9]
JavaScript
복사
정리
: 많은 라이브러리들이나 함수들이 해당 프로토콜을 따르도록 되어있기에 이터러블/이터레이터를 잘 사용할 수록 조합성이 높은 프로그램 구현이 가능하다.