이터러블 프로그래밍 또는 리스트 프로세싱 (Lisp): 홀수만 제곱해서 더하기

이토니·2024년 1월 17일
0

JavaScript

목록 보기
27/33
post-thumbnail

명령형 코드

  • 어떻게 그 일을 할 것인가가 구체적으로 작성되어 있다.
  • 익숙하면 한 눈에 들어오지만, 사실 사람이 읽기 어렵다.

// list에서 특정 개수의 홀수를 찾아 그 숫자의 제곱을 더하기
<script>
  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]);
</script>

for (const a of list): list 배열의 각 요소를 순회하는 루프

  • a: list 배열의 현재 요소
  • if (a % 2): a가 홀수인지 체크
  • const b = a * a;: 제곱을 계산
  • acc += b;: acc 변수에 b의 값을 더하기 (누적)
  • if (--limit == 0) break;: limit 변수를 하나 줄이고, 0이 되면 루프 종료

이터러블 프로그래밍 혹은 리스트 프로세싱 (Lisp)

  • 사람이 읽거나 이해하기 편한 코드

1. if를 filter로

  • else가 없는 iffilter로 바꿀 수 있다.
  • if 하나는 filter이다.
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>01/1</title>
  <script src="../fx.js"></script>
</head>
<body>
<script>
  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]);
</script>
  • if 문 대신에
  • L.filter(a => a % 2, list): list에서 홀수만을 필터링한다.

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

  • 값을 연산한 다음에 이후에 사용할 때는 map을 사용할 수 있다.
<script>
  function f2(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);
  }
  f2(3, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
</script>
  • 이전에는 값을 변화를 시키고 변수에 할당
  • L.filter로 걸러진 값을 L.map으로 제곱
  • map을 하며 a가 들어오면 제곱
  • for 문으로 하나씩 꺼내면서 더해지고 있음

3. break를 take로

  • 시간 복잡도를 줄이기 위해 take로 튜닝하여 사용할 수 있다.
<script>
  function f2(limit, list) {
    let acc = 0;
    for (const a of L.take(limit, L.map(a => a*a, L.filter(a => a % 2, list)))){
      acc += a;
      }
    console.log(acc);
  }
  f2(3, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
</script>
  • L.take로 값이 얼마나 남았든 최대 limit 만큼만 꺼내기

4. 축약 및 합산을 reduce로

  • 모든 값들을 상위 스코프에 둔 다음에 합산을 해야겠다 생각되면 reduce를 사용할 수 있다.
<script>
  function f2(limit, list) {
    console.log(
      _.reduce( (acc, a) => acc + a,
       0, // 초기값, 없어도 됨 (1부터 시작)
        L.take(limit, 
          L.map(a => a * a, 
            L.filter(a => a % 2, list)))));
      
  }
  f2(3, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
</script>

➡️ add로 빼주기

<script>
  const add = (a, b) => a + b;
  function f2(limit, list) {
    console.log(
      _.reduce(add,
        L.take(limit, 
          L.map(a => a * a, 
            L.filter(a => a % 2, list)))));
      
  }
  f2(3, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
</script>

1) list로 출발을 해서
2) 홀수만 걸러내서 (filter)
3) 모든 값들을 제곱 (map)
4) limit 까지만 뽑기로 예약 (take)
5) 모두 뽑아가며 add로 축약하며 출력한다.

➡️ go를 이용해서 파이프라인 형태로 순서를 뒤집어 더 읽기 쉽게 만들기

<script>
  const add = (a, b) => a + b;

  function f2(limit, list) {
    _.go(list,
      L.filter(a => a % 2),
      L.map(a => a * a),
      L.take(limit),
      _.reduce(add),
      console.log);
  }
  f2(3, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
  console.clear();
</script>

1) listfilter해서
2) map 으로 제곱을 하고
3) limit 만큼만 가져가서
4) add로 축약을 하며
5) 출력한다.

https://www.inflearn.com/course/%ED%95%A8%EC%88%98%ED%98%95_ES6_%EC%9D%91%EC%9A%A9%ED%8E%B8/dashboard

profile
cool & soft codes

0개의 댓글