L.flatten, L.deepFlat, L.flatMap

nn·2023년 6월 25일
0

flatten

중첩된 배열을 풀어서 리턴하는 flatten을 만들어보자

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


const L = {};
const isIter = (e) => {
  return e && e[Symbol.iterator];
}

L.flatten = function *(iter)  {
  for (const a of iter){
    
	if(isIter(a)){ 
      // 이터러블인경우 a를 돌면서 또 빼내기 
      for(const b of a){
      		yield b;
      }     
    } else {
      yield a;
  	}
}
}

우선 이터러블을 돌면서 이터러블의 요소가 다시 이터러블인지 확인하면서 요소를 하나씩 꺼내는 제너레이터를 만들었다.

L.flatten은 지연 평가가 되는 함수로, 연산이 필요할때 값이 생성되게 된다.

즉시 평가하는 flatten은 take연산을 통해 만들 수 있다.

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

takeAll 함수는 배열의 마지막 요소까지 모두 가져오는 함수이다.

L.flatten를 통해 지연적으로 동작하지만, 마지막 요소까지 모두 평가하는 takeAll함수를 pipe로 연속적으로 작성하여 flatten을 만들 수 있다.

L.deepFlat

2차원이아닌 3차원이상의 배열이 있는 경우 모두 펼치기 위한 deepFlat을 만들어보자.


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

iter을 재귀적으로 호출하면서 요소를 꺼내올 수 있다.

L.flatMap

flatMap은 map과 flatten을 함께 하는 함수이다.

const data = [[1, 2], [3, 4], [5, 6, 7]];

위 데이터가 있다. 중첩된 배열을 풀기위해서는 아래와 같이 할 수 있다.

go(
data,
L.map(a => a),
L.flatten,
takeAll,
log
) // [1,2,3,4,5,6,7] 출력

즉, L.map과 L.flatten을 함께 써서 사용할 수 있고 아래와 같이 사용할 수 있다.

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

go(
  data,
  L.flatMap(a => a),
  takeAll,
  log
  ) // [1,2,3,4,5,6,7] 출력

간략하게 아래의 순서로 작동된다.

  1. reduce로 작동되는 go 함수로 중첩 배열인 data와 L.flatMap이 작동된다.
  2. L.flatMap의 인자로 data가 들어간다.
  3. pipe함수로 인해 L.flatMap의 L.map이 먼저 실행된다.
  4. L.map은 지연적으로 평가하며 요소를 하나씩 꺼낼 준비를 한다.
    ([1,2] <- 1. 꺼낼 준비)
    ([3,4] <- 2.꺼낼 준비)
    ([5,6,7] <- 3.꺼낼 준비)
  5. L.flatten은 위 배열을 펼칠 준비를 한다.
  6. takeAll로 인해 배열의 모든 요소를 log에 전달한다. 이 부분에서 값이 평가된다.
  go(data,
    L.flatMap(map(a => a * a)),
    takeAll,
    log
  ) //  [1, 4, 9, 16, 25, 36, 49] 출력 

flatMap의 인자를 즉시 평가하는 함수로 변경하면 위와 같이 요소의 값을 변경할 수 있다.

또는 아래와 같이 응용해 볼 수 있다.

 go(
    [1, 2, 3],
    L.flatMap(L.range),
    takeAll,
    log,
  ) // [0, 0, 1, 0, 1, 2] 출력

L.range는 숫자를 인자로 받아서 해당 숫자만큼 0부터 증가하는 배열을 만든다.

1이 들어왔을때 [0]
2가 들어왔을때 [0,1]
3이 들어왔을때 [0,1,2] 가되며

이는 flatten으로 펼쳐져서 [0, 0, 1, 0, 1, 2] 이런 결과를 만들어낸다.

지연 평가 부분 중 가장 이해하기 어려운 부분이었고 잘 쓰기까지는 많은 훈련이 필요할 것 같다.ㅜㅜ

profile
내가 될 거라고 했잖아

0개의 댓글