Pure Reduce 함수 - Aggregator를 상태로 사용

7636 단어
복잡한 작업에 Array.reduce()를 사용할 때 우리는 부작용을 사용하는 경향이 있습니다(예: let 변수 또는 범위를 벗어난 개체 정의 및 반복하는 동안 수정).

다음은 애그리게이터를 상태로 사용하여 축소 기능을 순수하게 유지하는 쉬운 방법입니다.


모든 숫자를 합산하고 가장 큰 숫자를 두 번 더하는 감소 함수를 고려하십시오.
이전에 변경 가능한 변수를 선언하고 이를 사용하여 가장 큰 숫자를 추적한 다음 축소가 완료된 후에 추가할 수 있습니다.

let biggestNum = Number.NEGATIVE_INFINITY;

const sum = arr.reduce(
  (agg, val) => {
    biggestNum = Math.max(val, biggestNum);
    return agg + val;
  },
  0,
);

const sumAndBiggest = sum + biggestNum;


또는 reduce 함수 내부에 모든 관련 논리를 캡슐화할 수 있습니다.

const sumAndBiggest = arr.reduce(
  (agg, val, index, sourceArr) => {
    if (index === sourceArr.length - 1) {
      return agg.sum + val + agg.biggestNum;
    }

    return {
      sum: agg.sum + val,
      biggestNum: Math.max(val, agg.biggestNum),
    };
  },
  { sum: 0, biggestNum: Number.NEGATIVE_INFINITY },
);


두 가지를 알 수 있습니다.
  • 집계자를 상태로 사용합니다. 줄이고 있는 실제 합계와 지금까지 찾은 가장 큰 숫자를 포함합니다.
  • reduce 함수의 세 번째 및 네 번째 인수(현재 인덱스 및 반복할 배열에 대한 참조)를 사용하여 현재 반복이 마지막인지 확인합니다. 그렇다면 가장 큰 숫자를 추가하고 새 상태 대신 최종 합계를 반환합니다.



  • 이 방법은 reduce 함수에 조금 더 많은 논리를 추가합니다. 그렇다면 왜 사용해야 합니까?
    축소 작업에 필요한 모든 데이터를 캡슐화할 수 있기 때문입니다. 이는 다음을 의미합니다.
  • 감소가 완료된 후 남은 변수를 가져오지 않습니다. 누군가 코드를 읽거나 디버깅할 때, 첫 번째 예에서 biggestNum 변수가 다른 곳에서 사용되고 있는지 걱정할 필요가 없습니다.
  • 축소 기능이 순수 기능입니다. 살펴봐야 할 모든 것은 함수와 인수 내부에서 발생합니다. 이것은 또한 더 쉬운 디버깅을 의미합니다.
  • 상태의 모든 데이터는 더 이상 사용되지 않을 때 가비지 수집됩니다.


  • 안타깝게도 TypeScript는 reduce 에 대해 하나의 반환 값을 정의하는 옵션만 제공하며 최종 반환 값과 중간 반환 값을 구분할 수 없습니다.
    즉, reduce 함수를 두 유형을 모두 반환할 수 있도록 정의하고 as 키워드를 사용하여 애그리게이터의 유형을 사용하기 전에 확인해야 합니다.

    interface IReduceState {
      sum: number,
      biggestNum: number;
    }
    const sumAndBiggest = arr.reduce<number | IReduceState>(
      (agg, val, index, sourceArr) => {
        const { sum, biggestNum } = agg as IReduceState
        if (index === sourceArr.length - 1) {
          return sum + val + biggestNum;
        }
    
        return {
          sum: sum + val,
          biggestNum: Math.max(val, biggestNum),
        };
      },
      { sum: 0, biggestNum: Number.NEGATIVE_INFINITY },
    );
    


    이것에 대한 더 좋은 해결책이 있다면 알려주세요!

    즐거운 코딩하세요!


    Yonatan Kra 친절한 리뷰를 남겨주셔서 감사합니다.

    좋은 웹페이지 즐겨찾기