개발 기술/함수형 프로그래밍

함수형 코드 만들기, 홀수 n개 더하기

by GicoMomg (Lux) 2021. 9. 26.

명령형 프로그래밍 코드가 함수형 프로그래밍 코드로 매핑시킬 수 있다.
함수형 프로그래밍이 필요하면 사용하자
(멀티쓰레드, 변수의 원본이 바뀌면 안되는 경우,
라이브러리로 사용하는 경우, 시간복잡도를 줄이고 싶거나)

1. 홀수 n개 더하기

1) 시작하기전 알아야 할 점

  • 아래는 함수형 프로그래밍에서 사용하는 여러가지 함수 형태이다.
함수형태 설명
_.function - 결과값을 바로 나타내는 함수
L.function - lazy하게 동작하는 함수
- 실제 필요한 만큼만 생성하여 작업을 수행
- 실제 필요한 만큼만 생성하므로 결과를 바로 주지 않음
- [... L.func]를 사용하면 평가를 바로 내린 값을 얻을 수 있음
C.function - 동시적으로 동작하는 함수
- 멀티프로세서 환경에서 동작하는 동시성 프로그램을 작성할 때 사용

2) 변경 전 코드

  • 홀수인 원소 3개만 더해서 출력하는 코드이다.
    function f1(limit, list) {
    let result = 0;
    for(const a of list) {  // arr of array
      if (a%2) {
        const b = a*a;
        result += b;
        if (--limit === 0) break;
      }
    }
    console.log(result);
    }
    f1(3, [1,2,3,4,4,5,6,7,8,9,10]);

3) 함수형으로 바꿔보자!

(1) if => filter로 변경하자

  • L.filter: 특정 조건에 해당하는 이터러블(반복가능한 상태)
    function f2(limit, list) {
    let result = 0;
    for (const a of L.filter(a => a%2, list)){  //a of 필터로걸러진값
      if (a%2) {
        const b = a*a;
        result += b;
        if (--limit === 0) break;
      }
    }
    console.log(result);
    }
    f2(3, [1,2,3,4,4,5,6,7,8,9,10]);

(2) 원소 변형 => L.map를 이용하자

  • L.map(함수, 대상) : 원소의 값을 함수에 따라 변경할 때 사용

    function f3(limit, list) {
    let result = 0;
    
    for (const a of L.map(a => a*a, L.filter(a => a%2, list))){  
      result += a;
      if (--limit === 0) break;
    }
    console.log(result);
    }
    f3(3, [1,2,3,4,4,5,6,7,8,9,10]);

(3) break => take로 변경하자

  • L.take(limit, 대상) : 이터러블에서 limit개의 값을 얻고 싶을 때 사용
    function f4(limit, list) {
    let result = 0;
    for (const a of L.take(limit ,L.map(a => a*a, L.filter(a => a%2, list)))){  
      result += a;
    }
    console.log(result);
    }
    f4(3, [1,2,3,4,4,5,6,7,8,9,10]);

(4) 축약 및 합산을 reduce로

  • _.reduce: 어떤 값을 합산하고 새로운 값으로 리턴
  • reduce((누적값, 인자값) => 누적값 + 인자값, 누적초기값)
    function f5(limit, list) {
     console.log(
       _.reduce((acc, a) => acc + a, 0, 
           L.take(limit,
              L.map(a => a*a, 
                      L.filter(a => a%2, list))))
     )
    }
    f5(3, [1,2,3,4,4,5,6,7,8,9,10]);

  • reduce에서 사용하는 함수를 밖으로 빼서 사용할 수도 있다.
    const add = (acc, a) => acc + a;   //this!
    function f6(limit, list) {
    console.log(
      _.reduce(add,  //4. 다 더함
        L.take(limit,  //3. limit개수만큼만 뽑아내서
          L.map(a => a*a,   //2. 해당값을 제곱하고
            L.filter(a => a%2, list))))  //1.홀수만 걸러내고
    )
    }
    f6(3, [1,2,3,4,4,5,6,7,8,9,10]);

(5) 축약 및 합산을 reduce로

  • go : 인자를 받아 결과를 바로 산출함

    go함수는
    첫번째 인자가 시작값,
    두 번째 인자부터는 함수를 받는 데,
    첫번째 인자가 두번째 함수의 매개변수로 작용하여 결과를 만들고
    그 결과가 또 세번째 함수의 매개변수가 되어 결과를 만드는 과정을 수행함

function f7(limit, list) {
  _.go(
    list,
    L.filter(a => a%2), // 1. if === filter
    L.map(a => a*a),    // 2. 연산한 값을 사용할 때 === map
    L.take(limit),      // 3. 시간복잡도 줄일 때
    _.reduce(add),      //4. 모든 값들을 더할 때
    console.log);
}
f7(3, [1,2,3,4,4,5,6,7,8,9,10]);



참고하면 좋은 사이트


반응형

댓글