함수형 프로그래밍 - 이터러블 프로그래밍

MyeonghoonNam·2021년 8월 14일
1

함수형 프로그래밍

목록 보기
6/10
post-custom-banner

함수형 프로그래밍 시리즈 내용으로 계속 이어서 내용이 진행되므로 처음 부터 포스팅을 확인해주세요.

이터러블 프로그래밍

이터러블 프로그래밍은 리스트 프로세싱으로도 불리며 목록 형식의 (이터러블, 리스트.. 등) 데이터를 처리하는 프로그래밍을 말한다.

이번 포스팅에서 여러 예제들을 통하여 이터러블 프로그래밍(리스트 프로세싱)을 연습해 보자.


홀수 N개 더하기

아래 함수 f1()은 limit과 리스트를 인자로 받으며 리스트에서 limit 만큼의 홀수를 앞에서 부터 뽑아서 제곱한 후에 합을 반환한다.

먼저 아래의 경우 명령형 프로그래밍으로 구현되었으며 이 함수를 차례로 이터러블 프로그래밍을 통해 리펙토링 할 것 이다.

이를 통하여 함수형 프로그래밍 방식으로 코드를 바라보는 관점에 대하여 중점적으로 이해하자.

function f1(limit, list) {
  let acc = 0;
  for(const a of list) {
    if(a % 2) {
      const b = a * a;
      acc += b;          

      if(--limit === 0) break;
    }
  }

  console.log(acc);
}

f1(3, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

if를 filter로

if문을 filter로 대체해보자.

기존 홀수판별 조건이 지연성이 적용된 L.filter를 통하여 필요한 순간에만 값 평가가 이루어지는 이터레이터를 반환하여 그 후에 덧셈이 이루어지는 형태이다.

function f1(limit, list) {
  let acc = 0;
  for(const a of L.filter((a => a % 2), list)) {
    const b = a * a;
    acc += b;

    if(--limit === 0) break;
  }

  console.log(acc);
}

f1(3, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

값 변화 후 변수 할당을 map으로

L.map으로 L.filter로 걸러진 이터레이터를 관리한다.

function f1(limit, list) {
  let acc = 0;
  for(const a of L.map(a => a * a, L.filter((a => a % 2), list))) {
    acc += a;

    if(--limit === 0) break;
  }

  console.log(acc);
}

f1(3, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

break를 take로

take 함수를 통하여 뽑힌 요소의 수를 확인한다.

function f1(limit, list) {
  let acc = 0;
  for(const a of take(limit, L.map(a => a * a, L.filter((a => a % 2), list)))) {
    acc += a;
  }

  console.log(acc);
}

f1(3, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

reduce를 통한 축약 및 합산

reduce를 통해 조건을 만족하는 값들의 축약 및 합산을 진행한다.

go함수를 통해 파이프라인 형태로 좀 더 직관적으로 코드를 볼 수 있다.

function f1(limit, list) {
  go(
    list,
    L.filter(a => a % 2),
    L.map(a => a * a),
    take(limit),
    reduce(add),
    console.log
  )
}

f1(3, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

while 다루기

명령형 프로그래밍의 while은 함수형 프로그래밍에서 range로 다루기에 용이하다.

each 함수를 통해 반환된 형태의 데이터들에 효과를 줄 수 있다.

 // 명령형
 function f2(end) {
   let i = 0;
   while(i < end) {
     console.log(i);
     ++i;
   }
 }
 
 f2(10);

 // 함수형
 function f3(end) {
   go(
     L.range(end),
     each(console.log),
   )
 }
 
 f3(10);

별 그리기

별 그리기 예제를 직접 구현해보자.

go(
  L.range(6),
  L.map(range),
  L.filter(a => a.length > 0), 
  L.map(L.map((_ => '*'))),
  L.map(join('')),
  join('\n'),
  console.log
)

구구단

구구단 예제를 직접 구현해보자.

go(
  L.range(10),
  L.filter(a => a > 1),
  L.map(a => go(
    L.range(10),
    L.filter(a => a > 0),
    L.map(b => `${a}x${b}=${a*b}`),
    join('\n')
  )),
  join('\n\n'),
  console.log
)
profile
꾸준히 성장하는 개발자를 목표로 합니다.
post-custom-banner

1개의 댓글

comment-user-thumbnail
2023년 5월 6일

each에 대한 정의가 빠졌어요!

답글 달기