[JavaScript] L.flatten, flatten, L.deepFlat 함수 만들기

2023. 5. 9. 22:43· Node.js/JS
목차
  1. L.flatten 함수
  2. yield *
  3. L.deepFlat

L.flatten 함수

flatten이라는 함수를 만들고자 한다. 해당 함수는 임의로 배열이 섞여 있는 배열을 하나의 배열로 전환해주는 함수다. 또한, 지연 평가를 적용할 수 있는 함수다.

 

예를 들어, 아래와 같은 배열이 있다고 한다면

[[1, 2], 3, 4, [5, 6], [7, 8, 9]];

이를 하나의 배열로 처리해 아래와 같이 만들어 줄 수 있다.

[1, 2, 3, 4, 5, 6, 7, 8, 9]

이제 본격적으로 함수를 생성한다.

const isIterable = a => a && a[Symole.iterator];

L.flatten = function *(iter) {
  for (const a of iter) {
  	if (isIterable(a)) {} for (const b of a) yield b;
    else yield a;
  }
};

const it = L.flatten([[1, 2], 3, 4, [5, 6], [7, 8, 9]]);
console.log(it.next());

// {value: 1, done: false}

이처럼 L.flatten은 배열을 원소로 가지는 배열을 받아서 하나의 배열로 만들어 주는 함수이며, 이터레이터를 반환한다.

 

L.flatten이 있으면 즉시 평가하는 flatten도 쉽게 만들 수 있다.

더보기

이전에 만들었던 함수들

const curry = f =>
  (a, ...fs) => fs.length
  ? f(a, ...fs)
  : (...fs) => f(a, ...fs)
    
const reduce = curry((f, acc, iter) => {
  if (!iter) {
    iter = acc[Symbol.iterator]();
    acc = iter.next().value;
  for (const a of iter) {
  	acc = f(acc, a)
  }
  return acc;
};

const go = (...fs) => reduce((a, f) => f(a), ...fs);

const pipe = (...fs) => a => go(a, ...fs);

const take = (l, iter) => {
  const res = [];
  for (const a of iter) {
    res.push(a);
    if (res.length === l) return res;
  }
  return res;
};

const takeAll = take(Infinity);
const flatten = pipe(L.flatten, takeAll);

또한, 이터러블한 이터레이터를 반환하므로 아래와 같이 쓸 수도 있다.

console.log(take(6, L.flatten([[1, 2], 3, 4, [5, 6], [7, 8, 9]]));

yield *

yield * 을 활용해서 아래와 같이 코드를 바꿀 수 있다. yield *iterable은 for (const val of iterable) yield val; 과 같다.

L.flatten = function *(iter) {
  for (const a of iter) {
  	if (isIterable(a)) yield *a;
    else yield a;
  }
};

L.deepFlat

더 깊은 iterable을 모두 펼치고자 한다면 아래와 같이 L.deepFlat을 구현할 수 있다.

L.deepFlat = function *f(iter) {
  for (const a of iter) {
  	if (isIterable(a)) yield *f(a);
    else yield a;
  }
};

console.log([...L.deepFlat([1, [2, [3, 4], [[5]]]])]);
// [1, 2, 3, 4, 5];

이부분은 이전에 배웠던 함수의 연속이라 크게 와닿지 않았다. 그런데, yield *이나 deepFlat 부분은 새로 알 수 있어서 좋았다. yield * 패턴은 특히 깊은 배열을 풀어서 쓰는 데 유용해서 좋았다. 애스터리스크가 이터러블한 이터레이터를 반환하는 것이기 때문에 이렇게 반환하는 것 같다. 그리고 deepFlat의 경우 재귀적으로 작용하는 것으로 파악된다. 그래서 배열의 depth가 아무리 길다고 하더라도 모든 값들을 뽑아낼 수 있는 것 같다. 새로 배울 수 있는 점이라서 좋았다. 앞으로 제너레이터와 비동기적인 작동이 이어질 텐데 어떻게 효율적으로 코드를 작성할 수 있을지 기대된다.

 

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

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

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

[JavaScript] 이터러블 중심 프로그래밍 실무적인 코드  (0) 2023.05.11
[JavaScript] L.flatMap, flatMap  (0) 2023.05.10
[JavaScript] L.map, L.filter로 map과 filter 만들기  (0) 2023.05.09
[JavaScript] 함수 합성을 통해 find 함수 만들기  (0) 2023.05.08
[JavaScript] Array.prototype.join 보다 다형성 높은 join 함수  (0) 2023.05.08
  1. L.flatten 함수
  2. yield *
  3. L.deepFlat
'Node.js/JS' 카테고리의 다른 글
  • [JavaScript] 이터러블 중심 프로그래밍 실무적인 코드
  • [JavaScript] L.flatMap, flatMap
  • [JavaScript] L.map, L.filter로 map과 filter 만들기
  • [JavaScript] 함수 합성을 통해 find 함수 만들기
턴태
턴태
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)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

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

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.1
턴태
[JavaScript] L.flatten, flatten, L.deepFlat 함수 만들기
상단으로

티스토리툴바

단축키

내 블로그

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

블로그 게시글

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

모든 영역

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

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