JS의 reduce fold unfold 사용법 상세히 보기

4074 단어 JSreducefoldunfold

fold(reduce)


reduce를 말해 보세요. 이 함수를 좋아해서 코드량을 많이 절약했고 성명식의 모형도 있습니다. 흔히 볼 수 있는 도구 함수,flatten,deepCopy,mergeDeep 등은reduce로 우아하고 간결하게 이루어졌습니다.reduce는 fold라고도 하는데 본질적으로 하나의 접는 수조의 과정이다. 수조 중의 여러 개의 값을 연산을 거쳐 하나의 값으로 만든다. 매번 연산할 때마다 하나의 함수 처리가 있다. 이 함수는 reducer의 핵심 요소로 reducer라고 한다. reducer 함수는 2원 함수이고 하나의 단값을 되돌려준다. 흔한add 함수는 reducer이다.

const addReducer = (x, y) => x + y;
이add 함수는 바로 Reducer입니다. 가장 흔히 볼 수 있는 용법은 수조를 결합한 Reduce 방법으로 사용하는 것입니다

[1, 2, 3, 4, 5].reduce(addReducer, 0) // 15
reduce를 더욱 잘 이해하기 위해 다음은 서로 다른 사고방식으로 이 함수를 한 번 실현한다

for 사용...of


const reduce = (f, init, arr) => {
  let acc = init;
  for (const item of arr) {
    acc = f(acc, item);
  }
  return acc
}
//  
reduceFor(addReducer, 0, [1, 2, 3, 4, 5])  // 15

while 순환 사용하기


reduce = (f, init, arr) => {
  let acc = init;
  let current;
  let i = 0;
  while ((current = arr[i++])) {
    acc = f(acc, current);
  }
  return acc;
}

//  
reduceFor(addReducer, 0, [1, 2, 3, 4, 5])  // 15

더 fold의 실현 같아요.


위의 실현도 모두 이해하기 쉽지만 접기(fold)라는 과정이 나타나지 않은 것 같다. 접기는 수조에 대한 층층이 압박하는 작업이어야 한다. 위의 실현 수조와 논리는 사실 분리되었고 비교적 많은 중간 변수를 도입했다. 비록 내부에 부작용이 없지만.
사실 생각을 바꾸어 생각해 보면 상태를 매개 변수를 통해 전달하면 fold의 과정을 더욱 잘 나타낼 수 있다. 여기서 매개 변수는 값은 점차적으로 변화하는 수조와 계산 값을 가리키며 가능한 한 무상태로 할 수 있다. 진정한 순수 함수의 실현은 표현식이 없고 문장만 있는 것이다. 이것은 귀속으로 할 수 있다.아래의 실현은 꼬리로 돌아가는 Reduce로 실현되는 과정에서 수조와 계산값이 어떻게 변화하는지 알 수 있다.Fold라는 호칭에 딱 맞습니다.

function reduce(f, init, arr) {
  if (arr.length === 0) return init;
  const [head, ...rest] = arr;
  return reduceRecursion(f, f(init, head), rest);
}

//  
reduceFor(addReducer, 0, [1, 2, 3, 4, 5])  // 15

unfold


fold는 반대로unfold이고 unfold는 말 그대로 반대로reducer에 따라 일련의 값을 생성한다.이때 이것은 원래의 Reducer 실현이 (a, b)->c와 유사하다고 하면 반대로 c->[a, b]이다. 생성 서열은 매우 기본적인 조작이지만 바로 이 기본적인 조작이고 실현하는 사고방식도 많다. unfold를 소개하기 전에 서열을 실현하는 다른 방법을 보고 마지막으로 비교한다.
시퀀스의 실현

range(0, 100, 5)
결과를 기대하다
[0, 5, 10, ... 95]

수조 실현


이것은 더 이상 말하지 않겠다. 모두가 알고 있을 것이다.

range = (first, last, step) => {
  const n = (last - first) / step + 1;
  return Array.from({ length: n - 1 })
            .map((_, index) => first + index * step);
}
//  from 
// Array.from({ length: n }, (_, i) => first + i * step);

생성기 구현


생성 시퀀스에 또 하나의 유리한 도구가 있다. 그것이 바로generator이다. 생성기 생성기는 바로 데이터를 생성하는 데 쓰인다.generator는 교체기를 되돌려주고 시퀀스를 생성하기 쉽습니다

function* range(first, last, step) {
  let acc = first;
  while (acc < last) {
    yield acc;
    acc = acc + step;
  }
}
[...range(0, 100, 5)]
양자에 비해generator는 생성 과정을 중시하고,Array는 데이터 변화의 과정을 중시한다.

unfold 구현


unfold를 실현하기 전에 먼저 실현 사고방식을 정리하고fold와 마찬가지로 귀속을 사용하며 실현하는 과정에서 대응하는 데이터의 변화를 보아야 한다.대체적인 과정은 다음과 같다.
0 -> [0, 5]
5 -> [5, 10]
10 -> [10, 15]
15 -> [15, 20]
...
90 -> [90, 95]
95 -> [95, 100]
이를 통해 알 수 있듯이 과정은 바로fold가 반대이다. c->[a,b]에 부합된다. 초기 값은 한 개의 수조이기 때문에 unfold는 두 개의 매개 변수만 필요하고 다음과 같이 실현된다.

function unfold(f, init) {
  const g = (f, next, acc) => {
    const result = f(next);
    const [head, last] = result || [];
    console.log(last);
    return result ? g(f, last, acc.concat(head)) : acc;
  };
  return g(f, init, []);
}

range = R.curry((first, last, step) =>
  unfold(next => next < last && [next, next + step], 0)
)

//  
range(0, 100, 5)

총결산


이상은 Reduce와 하나의 생성 서열을 결합한 예입니다. fold와 unfold 두 가지가 fp프로그래밍에서 매우 중요한 개념을 간단하게 소개했습니다. 물론 그들의 기능은 생성 서열뿐만 아니라 강력한 기능도 많습니다.
이상은 JS의 Reduce fold unfold 용법에 대한 상세한 내용입니다. JS에 대한 더 많은 자료는 저희 다른 관련 글을 주목해 주십시오!

좋은 웹페이지 즐겨찾기