실무에서는 숫자와 문자열이 뒤섞인 배열을 만나게 되는 경우가 종종 있습니다. 이런 배열을 정렬할 때는 숫자들을 먼저 크기순(오름차순)으로 배치하고, 그 뒤에 문자열들을 알파벳순으로 정렬하는 것이 일반적입니다.
문제 예시
다음과 같은 배열이 있다고 가정해 보겠습니다.
const arr = [1, 'fdf', 'afv', 6, 47, 7, 'svd', 'bdf', 9];
위 배열을 정렬했을 때 기대하는 출력 결과는 다음과 같습니다.
[1, 6, 7, 9, 47, 'afv', 'bdf', 'fdf', 'svd']
커스텀 비교 함수 구현
JavaScript의 Array.prototype.sort() 메서드는 선택적으로 비교 함수(comparator)를 인자로 받습니다. 이 비교 함수 안에서 각 요소의 타입을 확인하고 규칙에 따라 값을 반환하면 원하는 정렬 순서를 얻을 수 있습니다.
const arr = [1, 'fdf', 'afv', 6, 47, 7, 'svd', 'bdf', 9];
const sorter = (a, b) => {
// 두 요소가 모두 숫자인 경우 → 수치 오름차순 정렬
if (typeof a === 'number' && typeof b === 'number') {
return a - b;
}
// a만 숫자인 경우 → 숫자가 앞에 오도록 함
else if (typeof a === 'number' && typeof b !== 'number') {
return -1;
}
// b만 숫자인 경우 → 숫자가 앞에 오도록 함
else if (typeof a !== 'number' && typeof b === 'number') {
return 1;
}
// 두 요소가 모두 문자열인 경우 → 사전식(알파벳) 정렬
else {
return a > b ? 1 : -1;
}
};
arr.sort(sorter);
console.log(arr);동작 원리 살펴보기
비교 함수는 두 개의 인자 a와 b를 받으며, 반환값에 따라 정렬 순서가 결정됩니다.
- -1 반환:
a가b보다 앞에 위치합니다. - 1 반환:
a가b보다 뒤에 위치합니다. - 0 반환: 두 요소의 순서를 변경하지 않습니다.
위 코드에서는 typeof 연산자로 타입을 판별하여 네 가지 경우를 처리합니다. 숫자끼리는 a - b로 수치를 비교하고, 숫자와 문자열이 비교될 때는 항상 숫자가 우선하도록 하며, 문자열끼리는 대소 연산자(>)로 알파벳순을 비교합니다.
실행 결과
콘솔에 출력되는 최종 결과는 다음과 같습니다.
[ 1, 6, 7, 9, 47, 'afv', 'bdf', 'fdf', 'svd' ]
숫자들은 먼저 오름차순(1, 6, 7, 9, 47)으로 정렬되고, 문자열들은 그 뒤에 알파벳순('afv', 'bdf', 'fdf', 'svd')으로 정렬된 것을 확인할 수 있습니다. 이처럼 비교 함수 하나만 잘 작성하면 복잡한 정렬 조건도 손쉽게 처리할 수 있습니다.