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

JavaScript로 배열의 최댓값·최솟값을 제외한 평균 구하기

문제 소개

숫자로 이루어진 배열을 인수로 받아, 최솟값과 최댓값을 제외한 나머지 요소들의 평균을 반환하는 JavaScript 함수를 작성해 보겠습니다.

예를 들어 다음과 같은 배열이 주어졌다고 가정해 봅시다.

const arr = [1, 4, 5, 3, 5, 6, 12, 5, 65, 3, 2, 65, 9];

이 배열에서 가장 큰 값(65)과 가장 작은 값(1)을 하나씩 제외한 뒤, 남은 요소들의 평균을 구하는 것이 목표입니다.

풀이 접근 방식

가장 효율적인 방법은 reduce() 메서드를 사용해 배열을 단 한 번만 순회하면서 세 가지 값을 동시에 누적하는 것입니다.

  • sum: 배열 전체 요소의 합계
  • min: 지금까지 확인한 값 중 최솟값
  • max: 지금까지 확인한 값 중 최댓값

누적 초기값으로 minInfinity, max-Infinity를 사용하면 어떤 숫자와 비교하더라도 올바르게 갱신됩니다.

구현 코드

const arr = [1, 4, 5, 3, 5, 6, 12, 5, 65, 3, 2, 65, 9];

const findExcludedAverage = arr => {
  const creds = arr.reduce((acc, val) => {
    let { min, max, sum } = acc;
    sum += val;
    if (val > max) {
      max = val;
    }
    if (val < min) {
      min = val;
    }
    return { min, max, sum };
  }, {
    min: Infinity,
    max: -Infinity,
    sum: 0
  });
  const { max, min, sum } = creds;
  // 전체 합에서 최솟값과 최댓값을 빼고, 개수에서도 2를 뺀 값으로 나눈다
  return (sum - min - max) / (arr.length - 2);
};

console.log(findExcludedAverage(arr));

출력 결과

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

10.818181818181818

코드 설명

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

  1. reduce()가 배열의 각 요소를 순회하며 합계(sum)에 값을 더하고, 현재 값이 기존 최댓값보다 크면 max를, 최솟값보다 작으면 min을 갱신합니다.
  2. 순회가 끝나면 creds 객체에는 배열 전체의 합계와 최솟값, 최댓값이 담기게 됩니다.
  3. 마지막으로 전체 합에서 최솟값과 최댓값을 각각 한 번씩 빼고, 요소 개수에서 2를 뺀 값으로 나누어 평균을 구합니다.

예제 배열의 경우 총합은 185이고, 여기서 최솟값 1과 최댓값 65를 빼면 119가 됩니다. 이를 13 − 2 = 11로 나누면 약 10.82라는 결과를 얻을 수 있습니다.

마무리

이처럼 reduce()를 활용하면 별도의 정렬 없이도 최솟값·최댓값을 제외한 평균을 O(n) 시간 복잡도로 간단하게 계산할 수 있습니다. 배열을 정렬한 뒤 양 끝 요소를 잘라내는 방식(O(n log n))보다 효율적이라는 점도 함께 기억해 두시면 좋습니다.