API를 사용하다 보면, 필요한 부분만 추출하거나 가공해야 하는 경우가 종종 발생합니다.

이번엔 월별 데이터와 학기별 데이터를 가져와 1학기, 2학기, 학기별 총계와 전체 총 합계를 

계산하는 기능을 만들어보겠습니다.

 

배열 메소드를 사용한 데이터 처리

제가 주로 사용하는 방법으로는 필요한 데이터만 추출하기 위해 API에서 데이터를 받아오는 함수에서

배열 메소드를 사용하는 방법입니다.


처음에는 API로부터 데이터를 받아올 때, 원하는 데이터 키 값만 추출하여 가져오면 

데이터 처리 속도가 빨라지지 않을까 생각했습니다. 

하지만, RESTful API를 사용할 때 데이터 처리 속도는 크게 달라지지 않습니다. 

서버(백엔드)에서 데이터를 클라이언트에 전달하기 전 이미 필터링 및 가공이 완료된 상태로 전달되기 때문입니다.

 

그럼 클라이언트에서 데이터를 가공하는 이유와 장점이 궁금하실텐데요. 

 

예를 들어, 클라이언트가 전체 데이터를 가져온 후 필요한 데이터만 추출하고 사용하면, 

이후 작업에서는 필요한 데이터만 사용하게 됩니다. 이는 불필요한 데이터 처리를 줄여주고, 

애플리케이션의 반응 속도를 향상시킬 수 있습니다.

 

예시 코드 📍

  const fetchMonthlyData = async () => {
    const res = await fetch(
      `https://testtest`
    );
    const data: MonthlyData[] = await res.json();

    const firstSemesterData = data.filter((pre: MonthlyData) => {
      return pre.month <= 8;
    });

    firstSemesterData.sort((a: MonthlyData, b: MonthlyData) => {
      return a.month - b.month;
    });

    const total = [
      {
        month: "1학기 합계",
        grade1: firstSemesterData.reduce(
          (total: number, currentValue: MonthlyData) =>
            (total = total + currentValue.grade1),
          0
        ),
        grade2: firstSemesterData.reduce(
          (total: number, currentValue: MonthlyData) =>
            (total = total + currentValue.grade2),
          0
        ),
        grade3: firstSemesterData.reduce(
          (total: number, currentValue: MonthlyData) =>
            (total = total + currentValue.grade3),
          0
        ),
        totalCounselee: firstSemesterData.reduce(
          (total: number, currentValue: MonthlyData) =>
            (total = total + currentValue.totalCounselee),
          0
        ),
        totalTime: firstSemesterData.reduce(
          (total: number, currentValue: MonthlyData) =>
            (total = total + currentValue.totalTime),
          0
        ),
        timePerWeek: firstSemesterData.reduce(
          (total: number, currentValue: MonthlyData) =>
            (total = total + currentValue.timePerWeek),
          0
        ),
      },
    ];

    const secondSemesterData = data.filter((pre: MonthlyData) => {
      return (
        pre.month === 9 ||
        pre.month === 10 ||
        pre.month === 11 ||
        pre.month === 12 ||
        pre.month === 1 ||
        pre.month === 2
      );
    });

    secondSemesterData.sort((a: MonthlyData, b: MonthlyData) => {
      a = "" + a;
      b = "" + b;
      return a.localeCompare(b, undefined, { numeric: true });
    });
    const secondTotal = [
      {
        month: "2학기 합계",
        grade1: secondSemesterData.reduce(
          (total: number, currentValue: MonthlyDatay) =>
            (total = total + currentValue.grade1),
          0
        ),
        grade2: secondSemesterData.reduce(
          (total: number, currentValue: MonthlyData) =>
            (total = total + currentValue.grade2),
          0
        ),
        grade3: secondSemesterData.reduce(
          (total: number, currentValue: MonthlyData) =>
            (total = total + currentValue.grade3),
          0
        ),
        totalCounselee: secondSemesterData.reduce(
          (total: number, currentValue: MonthlyData) =>
            (total = total + currentValue.totalCounselee),
          0
        ),
        totalTime: secondSemesterData.reduce(
          (total: number, currentValue: MonthlyData) =>
            (total = total + currentValue.totalTime),
          0
        ),
        timePerWeek: secondSemesterData.reduce(
          (total: number, currentValue: MonthlyData) =>
            (total = total + currentValue.timePerWeek),
          0
        ),
      },
    ];

    const monthSemesterSumTotal = [
      {
        month: "총 합계",
        grade1: total[0].grade1 + secondTotal[0].grade1,
        grade2: total[0].grade2 + secondTotal[0].grade2,
        grade3: total[0].grade3 + secondTotal[0].grade3,
        totalCounselee: total[0].totalCounselee + secondTotal[0].totalCounselee,
        totalTime: total[0].totalTime + secondTotal[0].totalTime,
        timePerWeek: total[0].timePerWeek + secondTotal[0].timePerWeek,
      },
    ];
    setMonthFirstSemesterData({
      firstSemesterData,
      total,
    });
    setMonthSecondSemester({
      secondSemesterData,
      secondTotal,
    });
    setMonthSemesterSumTotal(monthSemesterSumTotal);
  };

 

코드 설명 📍

 

1. fetchMonthlyData라는 함수를 만들고, API를 호출하여 데이터를 가져옵니다.
2. 가져온 데이터를 JSON 형식으로 변환합니다.

3. 1학기 (3~8월)까지의 데이터만 필터링해서 sort 메소드로 월별로 정렬 시켜줍니다.
4. reduce 메소드를 사용하여 학년별, 인원별, 시간별 각 값의 합계를 계산하여 데이터를 누적해서 더해줍니다.

5. 2학기 (9~2월)까지의 데이터도 필터링해서 월별 정렬시킵니다.
6. 1학기처럼 reduce를 사용하여 2학기의 총계를 계산합니다.
7. 위에서 가공한 total(1학기합계)과  secondTotal(2학기합계) 의 각 각의 값을 더해줍니다.

8. set함수안에 가공한 1학기데이터와 1학기 총계를 저장해줍니다.

9. 2학기 데이터도 set함수안에 저장해줍니다.

10. 마지막에 총 합계를 저장한 state훅을 만들어서 정제된 결과물을 넣어줍니다.

 

이렇게하면 배열 메소드로 데이터를 효과적으로 처리하고, 원하는 정보만 추출하여 필요에 따라

결과를 저장할 수 있습니다.

 

 

결론적으로, 전체 데이터를 한 번 가져와야 하는 상황에서도,

필요한 부분만 추출하고 사용하는 것이 성능 향상에 도움이 됩니다.

그러나 이러한 최적화 작업은 전체 데이터를 받아오는 시간 자체를 줄이지는 않습니다. 

따라서 가능하다면, 필요한 데이터만 백엔드에서 미리 가공하여 클라이언트에 전달하는 것이

전체 성능에 더 좋은 영향을 미칠 수 있습니다.

복사했습니다!