ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Functional] 순회와 이터러블
    programing/Language 2019. 7. 15. 16:43

    안녕하세요, Einere입니다.

    (ADblock을 꺼주시면 감사하겠습니다.)


    ES6에서의 리스트 순회

    for of

    // array
    const arr = [1, 2, 3];
    for(const e of arr) console.log(e);
    
    // set
    const set = new Set([1, 2, 3]);
    for(const e of set) consol.elog(e);
    
    // map
    const map = new Map([['a', 1], ['b', 2], ['c', 3]]);
    for(const e of map) consol.log(e);
    
    for(const e of map.entries()) console.log(e);
    // ["a", 1], ["b", 2], ["c", 3] 출력
    for(const e of map.keys()) console.log(e);
    // a, b, c 출력
    for(const e of map.values()) console.log(e);
    // 1, 2, 3 출력

     

    이터러블(iterable)/이터레이터(iterator) 프로토콜

    이터러블을 for of, 전개연산자 등과 함께 동작하도록 만든 규약. 혹은 모든 객체를 이터러블로 만들 수 있는 프로토콜.

    이터러블

    배열의 Symbol.iterator는 함수이다
    Symbol.iterator는 Iterator를 반환하는 함수다

    이터레이터를 반환하는 [Symbol.iterator]() 를 가진 값.

    Symbol.iterator는 Iterator를 반환하는 함수이다.

     

    이터레이터

    iterator.next()의 실행결과

    {value, done}객체를 반환하는 next() 를 가진 값.

    Iterator.next는 {value:any, done:boolean}객체를 반환한다.

     

    사용자 정의 이터러블

    // 3 2 1 을 순회하는 이터러블을 정의합니다
    const iterable = {
        // Symbol.iterator라는 속성을 가져야 한다
        [Symbol.iterator]() {
            let i = 3;
        
            // next라는 속성을 가진 객체, 즉 이터레이터를 반환한다
            return {
                // next 함수는 {value, done}을 반환한다
                next() {
                    // i가 0이라면 순환을 그만둔다
                    // 아니라면 순환을 계속한다
                    return {
                        value : i--,
                        done: i === 0
                    };
                },
                // 동일한 이터레이터를 반환한다
                // well-formed iterable
                [Symbol.iterator]() {
                    return this;
                }
            }
        }
    };
    // 함수 호출 스택을 출력하는 함수와 기록하는 함수를 가진 객체를 생성 및 반환하는 함수
    function buildFunctionCallLogObject() {
        let stack = [];
    
        const reverseIterable = {
            [Symbol.iterator]() {
                let i = stack.length;
                return {
                    next() {
                        i--;
                        return {
                            done: i < 0,
                            value: stack[i]
                        }
                    },
                    [Symbol.iterator]() {
                        return this;
                    }
                }
            }
        };
    
        return {
            // 함수 호출 스택을 순회하며 출력한다
            printExecutionSequence() {
                for(e of reverseIterable) console.log(e);
            },
            // 함수 호출 스택에 함수 호출 기록을 저장한다
            logExecutionSequence() {
                let errorStack = new Error().stack || '';
                let log = errorStack.split('\n')[2].trim();
    
                stack.push(log);
            }
        }
    }
    // 비구조화 할당
    const {printExecutionSequence, logExecutionSequence} = buildFunctionCallLogObject();

     

    잘 정의된 이터러블(well-formed iterable)

    잘 정의된 이터레이터

    잘 정의된 이터레이터는, 자기 자신을 반환하는 Symbol.iterator을 가지고 있는 이터레이터입니다.

    위 사진과 같이, 배열 arr의 이터레이터인 iter1은 자기자신을 Symbol.iterator의 반환값으로 가집니다.

    따라서 iter1과 iter2는 동일합니다.

     

    잘 정의된 이터레이터는 특성상 자신의 상태를 기억하는 이터레이터를 언제든지 사용할 수 있습니다.

    예를 들어, iter1.next()를 한 뒤 for(const e of iter1) { console.log(e); }를 하게 된다면 2와 3만 출력됩니다.

     

    이런 이터레이터를 가진 이터러블을 잘 정의된 이터러블라고 합니다.

     

     

    전개연산자

    const arr = [1, 2, 3];
    console.log(...arr);
    // 1 2 3 출력
    
    const arr1 = [4, 5, 6];
    console.log([...arr, ...arr1]);
    // [1, 2, 3, 4, 5, 6] 출력

    전개연산자도 이터러블을 이용합니다.

     

    전개연산자를 이용한 파라미터 다루기

    이러한 특성을 이용해 위와 같이 유동적인 파라미터를 다룰 수 있습니다.

     

     

     

    참고

    마이클 포거스, 『함수형 자바스크립트 : 새롭고 올바른 자바스크립트 프로그래밍 기법』, 한빛미디어(2014).

    유인동, 인프런 - 함수형 프로그래밍과 JavaScript ES6+

    https://medium.com/@chanakyabhardwaj/es6-reverse-iterable-for-an-array-5dae91c02904

     

    ES6 — Reverse Iterable for an Array - Cha - Medium

    To iterate over an array, a for..of loop can be used like below:

    medium.com

     

    댓글

Designed by black7375.