숫자로 이루어진 배열을 입력받아 그 안에서 최댓값(maximum value)이 위치한 인덱스를 반환하는 JavaScript 함수를 작성해 보겠습니다.
여기서 주의할 점은 배열에 최댓값이 하나만 존재하는 것이 아니라, 동일한 최댓값이 여러 번 반복해서 나타날 수 있다는 것입니다. 따라서 함수는 최댓값에 해당하는 모든 인덱스를 배열(array) 형태로 반환해야 합니다.
문제 해결 접근 방식
이 문제는 다음 두 단계로 해결할 수 있습니다.
1. Math.max()와 스프레드 연산자(...)를 사용해 배열 전체에서 최댓값을 구합니다.
2. reduce() 메서드를 활용해 배열을 순회하면서 각 요소가 최댓값과 일치하는 경우 해당 인덱스를 결과 배열에 추가합니다.
예제 코드
const arr = [10, 5, 4, 10, 5, 10, 6];
const findGreatestIndices = arr => {
// 1단계: 배열에서 최댓값 구하기
const val = Math.max(...arr);
// 2단계: 최댓값과 일치하는 요소의 인덱스만 수집
const greatest = arr.reduce((indexes, element, index) => {
if (element === val) {
return indexes.concat([index]);
} else {
return indexes;
}
}, []);
return greatest;
};
console.log(findGreatestIndices(arr));실행 결과
위 코드를 실행하면 콘솔에 다음과 같은 결과가 출력됩니다.
[ 0, 3, 5 ]
코드 동작 원리
입력 배열 [10, 5, 4, 10, 5, 10, 6]에서 최댓값은 10입니다. 이 값은 인덱스 0, 3, 5 위치에 세 번 등장하므로, 최종적으로 [0, 3, 5]라는 인덱스 배열이 반환됩니다.
filter()를 활용한 대안 방법
reduce() 대신 flatMap()이나 forEach()를 사용할 수도 있으며, 더 간결하게 작성하고 싶다면 다음과 같은 방법도 가능합니다.
const findGreatestIndices = arr => {
const val = Math.max(...arr);
return arr.flatMap((element, index) => element === val ? [index] : []);
};두 방법 모두 시간 복잡도는 O(n)으로 동일하며, 상황과 선호하는 코드 스타일에 따라 선택하여 사용하면 됩니다.