문제 소개
숫자 배열을 입력받아 아래 조건에 따라 정렬하는 자바스크립트 함수를 작성해 보겠습니다.
- 배열에 0이 포함되어 있다면, 모든 0은 배열의 맨 앞에 위치해야 합니다.
- 나머지 숫자들은 내림차순(큰 수부터 작은 수 순서)으로 배치해야 합니다.
예시
입력 배열이 다음과 같다면,
const arr = [4, 7, 0, 3, 5, 1, 0];
정렬이 적용된 후 배열은 다음과 같아야 합니다.
const output = [0, 0, 7, 5, 4, 3, 1];
해결 접근 방식
이 문제는 Array.prototype.sort() 메서드를 활용하면 간단하게 해결할 수 있습니다.
내림차순 정렬을 위해 비교 함수에서 첫 번째 인수에서 두 번째 인수를 뺀 값을 반환하고, 값이 falsy(즉, 0)인 경우에는 해당 값 대신 Number.MAX_VALUE를 사용합니다. 이렇게 하면 0이 일반적인 오름차순 기준과 무관하게 항상 배열의 앞쪽에 오도록 처리할 수 있습니다.
코드 구현
const arr = [4, 7, 0, 3, 5, 1, 0];
const specialSort = (arr = []) => {
const sorter = (a, b) => {
return (b || Number.MAX_VALUE) - (a || Number.MAX_VALUE);
};
arr.sort(sorter);
};
specialSort(arr);
console.log(arr);실행 결과
위 코드를 실행하면 다음과 같은 결과가 출력됩니다.
[
0, 0, 7, 5,
4, 3, 1
]동작 원리
비교 함수 sorter는 두 요소 a와 b를 비교할 때 다음과 같이 동작합니다.
- b가 0인 경우: b가
Number.MAX_VALUE로 대체되어 어떤 숫자보다도 큰 값으로 취급됩니다. 따라서 0은 항상 앞쪽으로 이동합니다. - a가 0인 경우: a가
Number.MAX_VALUE로 대체되어 비교 결과가 음수가 되고, 역시 0이 앞쪽에 위치하게 됩니다. - 둘 다 0이 아닌 경우: 일반적인 내림차순 비교(
b - a)가 수행됩니다.
즉, 이 방식은 0을 '가장 작은 값'이 아니라 '정렬 우선순위가 가장 높은 값'으로 다루기 위해 falsy 값을 최댓값으로 치환하는 트릭을 활용한 것입니다. 코드가 짧으면서도 의도를 명확히 드러내는 우아한 해결책이라 할 수 있습니다.