문제 상황
JavaScript 함수를 하나 작성해야 합니다. 이 함수는 숫자 배열 arr를 유일한 인자로 받으며, 배열에는 학생들이 취득한 점수가 들어 있습니다.
함수는 점수 배열 arr를 기준으로 각 학생의 등수를 담은 새로운 배열을 만들어 반환해야 합니다. 즉, 점수가 높은 순서대로 순위가 매겨집니다.
예를 들어 배열 arr에서 가장 높은 점수에 해당하는 위치의 출력 값은 1, 두 번째로 높은 점수는 2, 그다음은 3이 되는 식입니다.
입력 예시
const arr = [50, 47, 39, 32, 31];
함수 실행 후 기대되는 결과는 다음과 같습니다.
const output = [1, 2, 3, 4, 5];
결과 해설
배열 arr의 점수는 이미 내림차순으로 정렬되어 있습니다. 따라서 첫 번째 인덱스에 가장 높은 점수가 위치하며, 그 뒤로 차례대로 낮은 점수가 배치됩니다. 그래서 순위 배열도 자연스럽게 [1, 2, 3, 4, 5]가 됩니다.
구현 방법
핵심 아이디어는 다음과 같습니다.
- 원본 배열을 복사하여 내림차순으로 정렬합니다.
- 각 원소가 정렬된 배열에서 몇 번째 인덱스에 위치하는지
indexOf()로 찾습니다. - 인덱스에 1을 더해 순위로 변환한 뒤 결과 배열에 저장합니다.
실제 구현 코드는 아래와 같습니다.
const arr = [50, 47, 39, 32, 31];
const findRanks = (arr = []) => {
const { length } = arr;
// 원본 배열 보존을 위해 복사본 생성
let sortArray = arr.slice();
// 내림차순 정렬
sortArray.sort((a, b) => b - a);
const result = [];
for (let i = 0; i < length; i++) {
// 정렬된 배열에서 현재 점수의 인덱스를 찾아 순위로 변환
const j = sortArray.indexOf(arr[i]);
result.push(j + 1);
}
return result;
};
console.log(findRanks(arr));실행 결과
콘솔에 출력되는 결과는 다음과 같습니다.
[ 1, 2, 3, 4, 5 ]
참고 사항
indexOf()는 동일한 값이 여러 개 있을 경우 항상 첫 번째 인덱스를 반환하기 때문에, 같은 점수를 가진 학생들은 동일한 순위를 부여받습니다. 이는 일반적인 시험 성적 산정 방식(동점자 동률 처리)과 같은 동작입니다. 다만 indexOf()를 반복 호출하므로 배열이 클 경우 O(n²)의 시간 복잡도가 발생할 수 있으며, 성능이 중요한 환경이라면 Map 객체를 활용해 점수별 순위를 미리 저장하는 방식으로 최적화할 수 있습니다.