제너레이터와 이터레이터

ddullgi·2022년 6월 8일
0
post-thumbnail

본 포스트는 인프런의 함수형 프로그래밍과 JavaScript ES6+ 강의(링크)를 듣고 정리한 내용입니다.


제너레이터/이터레이터

  • 제너레이터: 이터레이터이자 이터러블을 생성하는 함수
function *gen() {
  yield 1;
  yield 2;
  yield 3;
}
let iter = gen();

console.log(iter[Symbol.iterator]); //ƒ [Symbol.iterator]() { [native code] }
console.log(iter[Symbol.iterator]() == iter); //true

console.log(iter.next()); //{ value: 1, done: false }
console.log(iter.next()); //{ value: 2, done: false }
console.log(iter.next()); //{ value: 3, done: false }
console.log(iter.next()); //{ value: undefined, done: true }

for (const a of gen()) {
  console.log(a);
}
//1
//2
//3
  • 제너레이터는 함수를 생성할때 앞에 *을 붙인다.

  • well formed iterator를 리턴하는 함수이다.

  • yield를 통해 value값을 생성할 수 있다.

  • return값을 지정해 줄 수 있다.

    function *gen2() {
      yield 1;
      yield 2;
      yield 3;
      return 200;
    }
    let iter2 = gen2();
    console.log(iter.next()); //{ value: 1, done: false }
    console.log(iter.next()); //{ value: 2, done: false }
    console.log(iter.next()); //{ value: 3, done: false }
    console.log(iter.next()); //{ value: 200, done: true }
    
    for (const a of gen()) {
      console.log(a);
    }
    //1
    //2
    //3
    • 단, 순회 할때는 리턴 값이 없이 순회가 된다.
    • return값은 done이 true가 될때 나오는 값이다.
  • 제너레이터는 순회할 값을 문장으로 표현하는 것이다.

    function *gen() {
      yield 1;
      if (false) yield 2;
      yield 3;
    }
    
    for (const a of gen()) {
      console.log(a);
    }
    //1
    //3
    • 이러한 문장을 순회할 수 있는 값으로 만들어준다.
    • 즉, 자바스크립트에서는 제너레이터를 통해 어떠한 값이나 상수도 순회할 수 있는 형태로 만들어준다.


odds

function *odds(l) {
  for (let i = 0; i < l; i++) {
    if (i % 2) yield i;
  }
}
let iter3 = odds(10);
console.log(iter3.next()); //{ value: 1, done: false }
console.log(iter3.next()); //{ value: 3, done: false }
console.log(iter3.next()); //{ value: 5, done: false }
console.log(iter3.next()); //{ value: 7, done: false }
console.log(iter3.next()); //{ value: 9, done: false }
console.log(iter3.next()); //{ value: undefined, done: true }
  • 홀수의 값만 출력해주는 제너레이터를 만들어 보았다.
  • 넣어 준 리미트 값이 될때까지 홀수만 출력해준다.

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;
  }
}
console.log(iter3.next()); //{ value: 1, done: false }
console.log(iter3.next()); //{ value: 3, done: false }
console.log(iter3.next()); //{ value: 5, done: false }
console.log(iter3.next()); //{ value: 7, done: false }
console.log(iter3.next()); //{ value: 9, done: false }
console.log(iter3.next()); //{ value: undefined, done: true }
  • 평가 될때마다 무한히 다음값을 출력해주는 infnity 제너레이터를 만들어서 위의 코드와 똑같이 동작하게 만들어 보았다.

function *limit(l, iter) {
  for (const a of iter) {
    if (a == l) return;
  }
}

let iter4 = limit(4, [1, 2, 3, 4, 5, 6]);
console.log(iter4.next()); //{ value: 1, done: false }
console.log(iter4.next()); //{ value: 2, done: false }
console.log(iter4.next()); //{ value: 3, done: false }
console.log(iter4.next()); //{ value: 4, done: false }
console.log(iter4.next()); //{ value: undefined, done: true }
  • 리미트 값과 iterable을 받아 리미트 값까지만 iterable을 출력해주는 제네레이터를 만들어 보았다.

  • 이 제네레이터를 이용하면 위의 코드를 더 재미있게 바꿀 수 있다.

    function* odds(l) {
      for (const a of limit(l, infinity(1))) {
        if (a % 2) yield a;
      }
    }
    let iter3 = odds(10);
    console.log(iter3.next()); //{ value: 1, done: false }
    console.log(iter3.next()); //{ value: 3, done: false }
    console.log(iter3.next()); //{ value: 5, done: false }
    console.log(iter3.next()); //{ value: 7, done: false }
    console.log(iter3.next()); //{ value: 9, done: false }
    console.log(iter3.next()); //{ value: undefined, done: true }
    for (const a of odds(12)) {
      console.log(a);
    }
    //1
    //3
    //5
    //7
    //9
    //11



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

console.log(...odds(10)); //1 3 5 7 9
console.log([...odds(10), ...odds(20)]); //[ 1,  3,  5, 7,  9,  1, 3,  5,  7, 9, 11, 13, 15, 17, 19 ]

const [head, ...tail] = odds(7);
console.log(head); //1
console.log(tail); //[ 3, 5, 7 ]

const [a, b, ...rest] = odds(10);
console.log(a); //1
console.log(b); //3
console.log(rest); //[ 5, 7, 9 ]
  • for of, 전개 연산자, 구조 분해, 나머지 연산자에서 활용할 수 있다.
profile
프론트엔드개발자를 꿈꾸는 예비 개발자

0개의 댓글