이번 글에서는 두 개의 숫자 배열을 인자로 받는 JavaScript 함수를 작성해 보겠습니다. 이때 두 번째 배열의 크기는 항상 첫 번째 배열보다 작다고 가정합니다.
함수의 목표는 첫 번째 배열을 오름차순으로 정렬하되, 두 배열에 공통으로 포함된 요소들을 배열의 맨 앞쪽에 배치하는 것입니다.
문제 예시
예를 들어, 다음과 같은 두 배열이 주어졌다고 가정해 봅시다.
const arr1 = [5, 4, 3, 2, 1];
const arr2 = [2, 3];
이 경우 기대되는 출력 결과는 다음과 같습니다. 공통 요소인 2와 3이 맨 앞에 오고, 나머지 요소들은 오름차순으로 정렬됩니다.
const output = [2, 3, 1, 4, 5];
구현 방법
이 문제는 JavaScript 배열의 내장 메서드인 sort()와 커스텀 비교 함수(comparator)를 활용하면 간단하게 해결할 수 있습니다.
비교 함수의 동작 로직은 다음과 같습니다.
- 비교 대상 중 한쪽이라도 두 번째 배열(
arr2)에 포함되어 있다면 우선순위가 높은 것으로 간주합니다. - 두 요소 모두 공통 요소가 아니라면 일반적인 숫자 오름차순 규칙(
a - b)을 따릅니다.
전체 코드는 아래와 같습니다.
const arr1 = [5, 4, 3, 2, 1];
const arr2 = [2, 3];
// 우선순위를 판단하는 헬퍼 함수
const sorter = (a, b, arr) => {
if (arr.includes(a)) {
return -1;
}
if (arr.includes(b)) {
return 1;
}
return a - b;
};
// 우선순위 정렬 함수
const prioritySort = (arr1, arr2) => {
arr1.sort((a, b) => sorter(a, b, arr2));
};
prioritySort(arr1, arr2);
console.log(arr1);
실행 결과
위 코드를 실행하면 콘솔에 다음과 같은 결과가 출력됩니다.
[ 2, 3, 1, 4, 5 ]
동작 원리 살펴보기
sorter 함수는 세 가지 경우를 처리합니다.
arr2에a가 포함된 경우:-1을 반환하여a가b보다 앞에 위치하도록 합니다.arr2에b가 포함된 경우:1을 반환하여b가a보다 앞에 위치하도록 합니다.- 둘 다 공통 요소가 아닌 경우:
a - b를 반환하여 일반적인 오름차순 정렬을 수행합니다.
이처럼 커스텀 비교 함수만 잘 설계하면, 별도의 추가 데이터 구조 없이도 우선순위가 반영된 정렬을 손쉽게 구현할 수 있습니다. 참고로 Array.prototype.sort()는 원본 배열을 직접 수정(mutate)하므로, 원본을 유지해야 하는 상황이라면 정렬 전에 slice()나 스프레드 연산자로 복사본을 만들어 사용하는 것이 좋습니다.