문제 상황
자바스크립트에서 객체 배열을 다룰 때, 특정 필드의 존재 여부를 기준으로 정렬해야 하는 경우가 종종 있습니다. 예를 들어 다음과 같이 이름 정보가 제각각인 객체 배열이 있다고 가정해 보겠습니다.
const people = [{
firstName: 'Ram',
id: 301
}, {
firstName: 'Shyam',
lastName: 'Singh',
id: 1016
}, {
firstName: 'Dinesh',
lastName: 'Lamba',
id: 231
}, {
id: 341
}, {
firstName: 'Karan',
lastName: 'Malhotra',
id: 441
}, {
id: 8881
}, {
firstName: 'Vivek',
id: 301
}];정렬 조건
요구 사항은 다음과 같습니다.
- firstName과 lastName을 모두 가진 객체가 가장 앞에 위치합니다.
- 두 필드 중 하나만 가진 객체가 그다음에 위치합니다.
- 어느 쪽도 가지지 않은 객체가 맨 뒤에 위치합니다.
해결 코드
단순히 true/false만 반환하는 비교 함수는 상황에 따라 일관성이 떨어질 수 있습니다. 가장 안전하고 명확한 방법은 각 객체의 우선순위를 숫자로 계산한 뒤, 그 차이를 비교 함수에서 반환하는 것입니다.
const getPriority = (obj) => {
// 이름 관련 필드 개수에 따라 우선순위 부여
if (obj.firstName && obj.lastName) return 0; // 둘 다 있음 → 최우선
if (obj.firstName || obj.lastName) return 1; // 하나만 있음
return 2; // 없음 → 최후순위
};
people.sort((a, b) => getPriority(a) - getPriority(b));
console.log(people);Array.prototype.sort()는 비교 함수가 음수를 반환하면 a를 앞에, 양수를 반환하면 b를 앞에 배치합니다. 따라서 두 객체의 우선순위 값 차이를 반환하면 원하는 순서대로 정렬됩니다.
실행 결과
콘솔 출력은 다음과 같습니다.
[
{ firstName: 'Karan', lastName: 'Malhotra', id: 441 },
{ firstName: 'Dinesh', lastName: 'Lamba', id: 231 },
{ firstName: 'Shyam', lastName: 'Singh', id: 1016 },
{ firstName: 'Ram', id: 301 },
{ firstName: 'Vivek', id: 301 },
{ id: 8881 },
{ id: 341 }
]
성과 이름을 모두 가진 객체들이 먼저 배치되고, 그다음 한쪽 이름만 있는 객체들, 마지막으로 이름 정보가 전혀 없는 객체들이 정렬된 것을 확인할 수 있습니다. 참고로 ES2019부터 sort()는 안정(stable) 정렬을 보장하므로, 동일한 우선순위를 가진 객체들은 원래 배열의 순서가 그대로 유지됩니다.