본문 바로가기

Javascript

reduce 를 이용한 함수 go() 를 구현해보자 - JS ES6+ 함수형 프로그래밍 - 18

본 시리즈는 인프런 강의 함수형 프로그래밍과 JavaScript ES6+ ( 지식 공유자 : 유인동 님 ) 의 강의를 수강하면서 내용을 제 방식대로 포스팅하는 글입니다.

 

함수형 프로그래밍과 JavaScript ES6+ - 인프런 | 강의

ES6+와 함수형 프로그래밍을 배울 수 있는 강의입니다. 이 강좌에서는 ES6+의 이터러블/이터레이터/제너레이터 프로토콜을 상세히 다루고 응용합니다. 이터러블을 기반으로한 함수형 프로그래밍,

www.inflearn.com

이 내용은 이전 게시물과 이어집니다.

 

함수형 프로그래밍 에서는 코드를 값으로 다루는 아이디어를 많이 사용한다.

코드를 값으로 다룰수 있기 때문에 함수가 코드인 함수를 받아서 평가하는 시점을 원하는대로 다룰수가 있기 때문에

 코드의 표현력을 높인다던지 좋은 아이디어를 많이 가지고 있다.

코드를 값으로 다루는 함수들을 만들어서, 더 표현력을 좋게 하고 읽기 좋게하는 아이디어들을 확인해보자

 

이전 포스트에서 작성한 products 를 축약하는 코드는 함수중첩이 되어 있다보니 코드를 읽을때 조금 복잡해 보이는 경향이 있다.

우리가 읽기 편하게 변경해 보자.

const products = [
    { name: "반팔티", price: 15000 },
    { name: "긴팔티", price: 20000 },
    { name: "핸드폰케이스", price: 15000 },
    { name: "후드티", price: 30000 },
    { name: "바지", price: 25000 },
  ];

  const add = (a: number, b: number) => a + b;

  // 이전에 만들어 보았던 map filter reduce 함수의 중첩 사용을
  // 좀더 보기 좋게 만들어보는 코드를 작성해보자
  log(
    reduce(
      add,
      map(
        (product) => product.price,
        filter((product) => product.price < 20000, products)
      )
    )
  );

  // go() 라는 함수를 만들어 보자.
  const go = () => {

  }

  // 이 함수는 연속적으로 실행하여 하나의 값을 출력하는 함수이다.
  // 예를 들면 아래와 같다.
  go (
    0,
    a => a + 1,
    a => a + 10,
    a => a + 100,
    log
 );

그렇다면 이 go() 함수는 어떤 값을 받고 어떻게 동작해야하는 것일까?

  // 인자들을 통해서 하나의 값으로 축약을 해나가야한다.
  // 받아오는 인자들이 배열 리스트라고 가정하면 아래 코드와 같고,
  // 받는 배열의 첫번째 인자를 다음 인자로 전달하고, 그 결과를 또 그 다음 인자로 전달하는 형태가 되야한다.
  // argus 를 하나의 값을 축약해나가는, reduce 와 같은 형태이다.
  const go = (...argus : any[]) => {
    log(argus) // [0, f, f, f, f]
  }

  go ([
    0,
    a => a + 1,
    a => a + 10,
    a => a + 100,
    log
  ])

이제 고민하지 않고, reduce() 를 사용하여 구현해보자.

  // reduce 인자의 첫번째 값으로 [0,f,f,f,f] 중 0이 초기값으로 전환되어 들어올것이고,
  // 두번째 값으로 두번째 함수가 들어오게 될것이다.
  // 그래서 두번째 함수인 a => a+1 이 실행되게 되면 1 이라는 값으로 평가가 될것이고,
  // 이 값은 다시 reduce 의 value 인자로 들어가게 되고, 세번째 함수가 fn 인자로 들어가게되어 실행될것이다.
  // 마지막에 log 함수에도 이전의 결과값이 전달이 되면서 log(value) 로 실행될것이다.
  
  const go = (...argus: any[]) => reduce((value, fn) => fn(value), argus); // 111

  go([
    0,
    (a: number) => a + 1,
    (a: number) => a + 10,
    (a: number) => a + 100,
    log,
  ]);

이렇게 값을 축약하는 형태는 reduce 를 사용하면 쉽게 구현할수 있게 된다.