Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

JavaScript로 배열 합계의 특정 퍼센트 이하가 되는 요소 추출하기

프로그래밍을 하다 보면 숫자 배열에서 특정 조건을 만족하는 요소들을 추출해야 하는 경우가 자주 있습니다. 이번 글에서는 배열 전체 합계를 기준으로, 주어진 퍼센트 이하가 될 때까지 앞쪽 요소들을 순서대로 모으는 함수를 JavaScript로 구현해 보겠습니다.

문제 정의

다음과 같은 숫자 리터럴 배열이 있다고 가정해 봅시다.

const numbers = [10, 6200, 20, 20, 350, 900, 26, 78, 888, 10000, 78, 15000, 200, 1280, 2000, 450];

우리가 작성할 함수는 두 개의 인자를 받습니다. 첫 번째는 숫자 배열이고, 두 번째는 0부터 100 사이의 값으로 특정 백분율(%)을 나타냅니다. 편의상 이 값을 x라고 부르겠습니다.

함수는 원본 배열의 처음 n개 요소 중에서, 그 합이 전체 합계의 x%보다 작거나 같은 부분 배열을 반환해야 합니다. 즉, 요소를 하나씩 더해가다가 기준치를 초과하는 순간 멈추고, 그때까지 모은 요소들만 반환하는 것입니다.

간단한 예시

const numbers = [12, 10, 6, 8, 4, 2, 8];

이 배열의 전체 합계는 50입니다. 두 번째 인자로 25를 넘겨주면(x = 25), 전체 합계인 50의 25%, 즉 12.5와 같거나 그보다 작아질 때까지의 첫 n개 요소를 반환해야 합니다.

첫 번째 요소 12는 기준값 12.5 이하이므로 포함되지만, 여기에 두 번째 요소 10을 더하면 22가 되어 기준값을 초과합니다. 따라서 이 경우에는 첫 번째 요소 하나만 담긴 배열이 반환됩니다.

구현 코드

구현 방식은 간단합니다. 먼저 reduce() 메서드로 배열의 전체 합계를 구하고, for 반복문 안에서 요소를 하나씩 누적하면서 조건에 맞는 새로운 배열을 만들어 줍니다.

const numbers = [10, 6200, 20, 20, 350, 900, 26, 78, 888, 10000, 78, 15000, 200, 1280, 2000, 450];

const findPercent = (arr, percent) => {
  const sum = arr.reduce((acc, val) => acc + val);
  const part = [];
  let curr = 0;
  for (let i = 0; i < arr.length; i++) {
    curr += arr[i];
    if (curr <= (sum * percent) / 100) {
      part.push(arr[i]);
    } else {
      break;
    }
  }
  return part;
};

console.log(findPercent(numbers, 35));
console.log(findPercent(numbers, 5));
console.log(findPercent(numbers, 65));
console.log(findPercent(numbers, 95));

실행 결과

콘솔 출력 결과는 다음과 같습니다.

[
    10, 6200, 20, 20,
    350, 900, 26, 78,
    888
]
[ 10 ]
[
    10, 6200, 20,
    20, 350, 900,
    26, 78, 888,
    10000, 78
]
[
    10, 6200, 20, 20,
    350, 900, 26, 78,
    888, 10000, 78, 15000,
    200, 1280
]

코드 동작 원리

동작 과정을 단계별로 살펴보면 다음과 같습니다.

  • 전체 합계 계산: reduce() 메서드를 사용해 배열의 모든 요소를 더한 총합을 구합니다.
  • 누적 합 비교: 반복문을 돌며 각 요소를 curr 변수에 누적하고, 이 값이 전체 합계의 percent% 이하인지 확인합니다.
  • 조건 충족 시 추가: 조건을 만족하면 해당 요소를 결과 배열 part에 push합니다.
  • 조건 초과 시 종료: 기준값을 초과하는 순간 break로 반복문을 빠져나오고, 지금까지 모은 배열을 반환합니다.

이 방식은 배열을 한 번만 순회하면 되므로 시간 복잡도가 O(n)으로 매우 효율적입니다. 덕분에 데이터 양이 많아져도 성능 저하 없이 안정적으로 동작합니다. 또한 로직이 단순하기 때문에 상위 n% 매출 집계, 누적 분포 분석 등 실무에서도 다양하게 응용할 수 있습니다.