본문 바로가기
개발자 도전기/[STUDY] JS || TS

JavaScript | FP && ES6+ | L.flatten, L.flatMap, flatMap, 지연성/이터러블 실무 예제

by 답수 2022. 2. 16.
728x90
반응형

 

 

L.flatten

L.flatten 함수는 [..[1, 2], 3, 4, ...[7, 8, 9]] 같은 배열이 있을 때 [1, 2, 3, ... 7, 8, 9]와 같이 하나의 배열로 만드는 함수다.

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

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

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

console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());
// console.log([...it]);

 

 

yield *

'yield *' 을 활용하면 위의 L.flatten 코드를 아래와 같이 변경할 수 있다. 

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

 

'yield *iterable'은 'for (const v of iterable) yield v' 와 같다.

 

 

L.deepFlat

만약 깊은 iterable을 모두 펼치고 싶다면 'L.deeFlat'을 재귀적으로 구현하여 사용할 수 있다.

L.deepFlat = function* f(iter) {
  for (const a of iter) {
    if (isIterable(a)) yield* f(a);
    else yield a;
  }
};
log([...L.deepFlat([1, [2, [3, 4], [[5]]]])]);
// [1, 2, 3, 4, 5];

 

 

L.flatMap, flatMap

FlatMap은 map과 flatten 함수를 동시에 실행하는 함수로 최신 자바스크립트에 나온 기술이라고 한다. 왜? 자바스크립트가 기본적으로 지연적으로 동작하지 않기 때문에 시간복잡도 측면에서 비효율적으로 작동했다.

L.flatMap = curry(pipe(L.map, L.flatten));
const flatMap = curry(pipe(L.map, flatten));

let it = L.flatMap(a => a, [[1, 2], [3, 4], [5, 6, 7]]);

console.log([...it]);

 

 

지연성 / 이터러블 실무 코드

실무에서 필터, 맵 등의 메소드를 정말 자주 사용한다고 한다. 아래 예제로 살펴 보자.

 

let users = [
    {
      name: 'a', age: 21, family: [
        {name: 'a1', age: 53}, {name: 'a2', age: 47},
        {name: 'a3', age: 16}, {name: 'a4', age: 15}
      ]
    },
    {
      name: 'b', age: 24, family: [
        {name: 'b1', age: 58}, {name: 'b2', age: 51},
        {name: 'b3', age: 19}, {name: 'b4', age: 22}
      ]
    },
    {
      name: 'c', age: 31, family: [
        {name: 'c1', age: 64}, {name: 'c2', age: 62}
      ]
    },
    {
      name: 'd', age: 20, family: [
        {name: 'd1', age: 42}, {name: 'd2', age: 42},
        {name: 'd3', age: 11}, {name: 'd4', age: 7}
      ]
    }
];

 

go(users,
    L.flatMap(u => u.family),
    L.filter(u => u.age > 20),
    L.map(u => u.age),
    take(4),
    reduce(add),
    console.log);   // 209

 

728x90
반응형
LIST

댓글