[JavaScript] L.map, L.filter로 map과 filter 만들기

2023. 5. 9. 07:09· Node.js/JS
목차
  1. L.map으로 map 만들기
  2. L.filter로 filter 함수 만들기
  3. 코드 단순화

L.map으로 map 만들기

이터러블 객체를 순회하면서 일괄적으로 함수를 적용하는 map 함수를 지연평가를 적용한 L.map을 통해서 구현할 수 있다.

 

먼저 L.map의 코드는 아래와 같다.

L.map = curry(function *(f, iter) {
  iter = iter[Symbol.iterator]();
  let cur;
  while (!(cur = iter.next()).done) {
    const a = cur.value;
    yield f(a);
  }
});

그리고 map 코드는 아래와 같다.

const map = curry((f, iter) => {
  let res = [];
  iter = iter[Symbol.iterator]();
  let cur;
  while (!(cur = iter.next()).done) {
  	const a = cur.value;
    res.push(f(a));
  }
  return res;
});

L.map과 map은 혼용이 가능한데, 그 이유는 둘 모두 이터러블한 객체를 받으며 이터러블 객체에서 이터레이터를 꺼내 순회할 수 있기 때문이다.

const map = curry((f, iter) => go(
  iter,
  L.map(f)
});

console.log(map(a => a + 10, [0, 1, 2, 3]));
// Generator {<suspended>}

위와 같이 작성하면 일단 논리적으로 iterable 객체를 받아 L.map을 수행할 수 있다. 여기서 값을 평가하여 실제 map 함수와 동일하게 동작할 수 있도록 구현한다.

const map = curry((f, iter) => go(
  iter,
  L.map(f),
  take(Infinity)
});

console.log(map(a => a + 10, L.range(4)));
// (4) [10, 11, 12, 13]

iterable의 길이가 어느 정도이든 모든 값을 순회하기 때문에 기존 map과 동일하게 동작한다.

 

go의 첫 번째 인자인 iter를 L.map 함수에 바로 넣을 수 있다.

const map = curry((f, iter) => go(
  L.map(f, iter),
  take(Infinity),
});

여기서 f와 iter를 받아서 바로 L.map에 전달하기에 이를 pipe 함수로 전환할 수도 있다.

const map = curry(pipe(
  L.map,
  take(Infinity)
});

L.filter로 filter 함수 만들기

filter도 동일하게 iterable 객체를 받아서 로직을 수행하기 때문에 앞선 사례처럼 L.filter로 filter함수를 대체할 수 있다.

 

먼저 L.filter 함수는 다음과 같다.

L.filter = curry(function *(f, iter) {
  iter = iter[Symbol.iterator]();
  let cur;
  while (!(cur = iter.next()).done) {
  	const a = cur.value;
    if (f(a)) {
      yield a;
    }
  }
});

filter 함수는 다음과 같다.

const filter = curry((f, iter) => {
  let res = [];
  iter = iter[Symbol.iterator]();
  let cur;
  while (!(cur = iter.next()).done) {
    const a = cur.value;
    if (f(a)) res.push(a);
  }
  return res;
});

전체적으로 동일한 형태를 갖고 있으며, 이터러블 객체를 받아 L.filter를 수행한 후에 take(Infinity)로 값을 모두 가져오므로, map과 동일하게 단순화할 수 있다.

const filter = curry(pipe(L.filter, take(Infinity)));

console.log(filter(a => a % 2, [0, 1, 2, 3]));

코드 단순화

take(Infinity)는 map과 filter에서 동일하게 쓰이므로 변수에 저장해 사용하는 것도 방법이다.

const takeAll = take(Infinity);

다음으로 L.map과 L.filter의 경우 값을 하나하나 평가하기 위해 절차적으로 코드를 작성했는데, 단순하게 표현하자면 아래와 같다.

L.map = curry(function *(f, iter) {
  for (const a of iter) {
    yield f(a);
  }
});
L.filter = curry(function *(f, iter) {
  for (const a of iter) {
  	if (f(a)) yield a;
  }
});

사실 L.map과 L.filter라는 함수형이 조금 생소하게 느껴지는데 이를 map, filter로 바꿔서 표현할 수 있어서 좋았다. 또한, 지연평가를 수행하기 때문에 Inifinity를 자유롭게 사용할 수 있다는 점도 큰 메리트였다. 이를 통해서 map, filter와 동일하게 표현할 수 있기 때문이다. 또한, curry와 pipe의 놀라운 효과에 매번 놀란다. curry는 나중에 인자를 받아서 처리할 수 있다는 첨이 가독성을 높여주는 데 많은 도움이 된다. 그리고 pipe도 마찬가지로 중복된 코드를 줄일 수 있어서 단순화에 강점이 있다. 아직 curry와 pipe의 합성 원리를 제대로 이해하지는 못했기 때문에 내부 로직을 하나하나 풀어서 이해해보고 싶다.

 

출처: 인프런 함수형 프로그래밍과 JavaScript ES6+

저작자표시 비영리 (새창열림)

'Node.js > JS' 카테고리의 다른 글

[JavaScript] L.flatMap, flatMap  (0) 2023.05.10
[JavaScript] L.flatten, flatten, L.deepFlat 함수 만들기  (0) 2023.05.09
[JavaScript] 함수 합성을 통해 find 함수 만들기  (0) 2023.05.08
[JavaScript] Array.prototype.join 보다 다형성 높은 join 함수  (0) 2023.05.08
[JavaScript] map, filter & reduce로 결과를 만드는 함수 생성  (0) 2023.05.07
  1. L.map으로 map 만들기
  2. L.filter로 filter 함수 만들기
  3. 코드 단순화
'Node.js/JS' 카테고리의 다른 글
  • [JavaScript] L.flatMap, flatMap
  • [JavaScript] L.flatten, flatten, L.deepFlat 함수 만들기
  • [JavaScript] 함수 합성을 통해 find 함수 만들기
  • [JavaScript] Array.prototype.join 보다 다형성 높은 join 함수
턴태
턴태
import { Dream } from "future";
턴태
턴태의 밑바닥부터 시작하는 de-vlog
턴태
전체
오늘
어제
  • ROOT (187)
    • Node.js (37)
      • ES6 (1)
      • TypeScript (3)
      • Express.js (16)
      • NestJS (16)
      • JS (24)
    • 프론트엔드 (29)
      • CS (5)
    • 백엔드 (1)
      • 검색 (2)
      • Database (1)
    • 기타 툴 (1)
      • git (1)
    • 데브옵스 & 인프라 (19)
      • Kubernetes (15)
      • Docker (2)
      • Monitoring (1)
      • IaC (1)
    • Algorithm (90)
      • Implementation & simulation (5)
      • Math (4)
      • Brute Force (1)
      • String (0)
      • Graph (5)
      • Recursion & Backtracking (19)
      • Divide & Conquer (2)
      • Dynamic Programming (18)
      • Greedy (13)
      • Priority Queue (2)
      • Binary Search (6)
      • Data Structure (7)
      • Shortest Path (5)
      • Minimum Spanning Tree (1)
      • Sorting (1)
      • Prefix Sum (1)
    • Linux (1)
      • Ubuntu (1)
    • Diary (5)
      • Algorithm (1)
      • Conference (1)
      • Retrospective (3)
    • Book (0)
      • Self-Development (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 네스트
  • backtracking
  • 자바스크립트
  • 토이프로젝트
  • 노드
  • 함수형 프로그래밍
  • 다이나믹 프로그래밍
  • 쿠버네티스
  • 디프만
  • N과 M
  • dynamic programming
  • 인프런X디프만
  • 인프런
  • GREEDY
  • 백준
  • baekjoon
  • TypeScript
  • python
  • Toy Project
  • 타입스크립트
  • 백트래킹
  • k8s
  • 오먹
  • Express
  • node.js
  • 파이썬
  • 익스프레스
  • nestjs
  • Kubernetes
  • Omuk

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.1
턴태
[JavaScript] L.map, L.filter로 map과 filter 만들기
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.