for문 대신 map? reduce?

오병진·2022년 4월 29일
1

FxTs

목록 보기
3/4

이터러블을 이용한 코딩은 for문을 이용할 수 있지만
함수형 코딩을 위해서는 for문은 지향되지는 않습니다.

for문을 다루다가 여러 에러가 발생된다던지,
조건을 설정하다가 의도치않은 버그로 인하여 시간 소요가 발생할 수 있기 때문이죠

여러 예제들을 살펴볼까요

map

import { pipe, map, reduce, take, toArray } from "@fxts/core"

function newArr(n) {
  let i = 1;
  const res = [];
  while (i < n) res.push(i++);
  return res;
}

function solution1(n){
  const arr1 = newArr(n);
  let arr2 = [];
  
  for(let i = 0; i < arr1.length; i++){
    arr[i] *= 2;
  }
  console.log(arr2); // expected [2, 4, 6, 8, 10, 12, 14, 16, 18]
}

solution1(10);

다음과 같은 for문을 map으로 깔끔하게 줄일 수 있습니다.

function solution2(n){
  const arr1 = newArr(n);
  const arr2 = arr1.map((v) => v * 2);
  console.log(arr2); // expected [2, 4, 6, 8, 10, 12, 14, 16, 18]
}

solution2(10);

그리고 FxTs를 통한다면 다음과 같죠

function solution3(n){
  const arr2 = pipe(
    newArr(n),
    map((v) => v * 2),
    toArray
  );
  console.log(arr2);
}

solution3(10);

Arr을 생성하고, map으로 반복하여 toArray, 즉 array로 출력합니다.
복잡한 코드가 아니라 solution2solution3의 차이가 별로 나지는않네요.

reduce

그렇다면 저번시간에 한 합계 구하는 것을 reduce로 해보도록 하겠습니다.

function solution1(size, j){
  function * numArr(n){
    let i = 1;
    while (i < n) yield i++;
  }

  let sum = 0;
  let i = 0;
  for(const item of numArr(size)){
    if(item % 2 === 0){
      sum += item;
      i++;
    }
    else if(i >= j) break;
  }
  return sum; // 6
}

console.log(solution1(1000, 10)); // 110

저번시간에 한 generator를 이용한 합계를 구하는 코드인데
조건이 합 100이상인 것을 j 만큼 더하는 것으로 수정해보았습니다.

이를 한번 reduce로 바꾸고, FxTs로 해보겠습니다.

function solution2(size, j){
  const arr1 = newArr(size);
  
  let i = 0;
  return arr1.reduce((acc, cur) => {
    if(i >= j) { return acc }
    cur % 2 === 0 && i++;
    return acc + (cur % 2 === 0 ? cur : 0);
  }, 0);
}

console.log(solution2(1000, 10)); // 110

이렇게 처리할 수 있습니다.
다만 generator로 얻은 이점이 사라져버렸네요.

function solution3(size, j){
  function * numArr(n){
    let i = 1;
    while (i < n) yield i++;
  }
  
  return pipe(
    numArr(size),
    filter((v) => v % 2 === 0),
    take(j),
    reduce((a, b) => a + b),
  );
}

console.log(solution3(1000, 10)); // expected 110

iterator를 돌리면서 2의 배수들을 j개만큼 take해서 sum을 하는 코드입니다.
순서대로 진행되며, 직관적이죠

다음에는 if 대신 filter로 만나뵙겠습니다 :D

profile
지나가는 사람입니다. 마저 지나갈게요 :D

1개의 댓글

comment-user-thumbnail
2023년 3월 16일

안녕하세요 reduce에 seed를 줄 순 없을까요?

답글 달기