JavaScript로 개발하다 보면 객체 배열을 여러 조건에 따라 정렬해야 하는 경우가 자주 발생합니다. 이번 글에서는 두 개의 속성을 동시에 기준으로 배열을 정렬하는 방법을 살펴보겠습니다.
문제 상황
다음과 같은 객체 배열이 있다고 가정해 보겠습니다.
const arr = [
{ resVal: "25FA15", resFlow: 49, resName: "Rendimiento Tri-Seal Completo", resPhoto: "Tri-Sealseries.png", resHP: 1.5 },
{ resVal: "25FA2", resFlow: 52, resName: "Rendimiento Tri-Seal Completo", resPhoto: "Tri-Sealseries.png", resHP: 2 },
{ resVal: "45FA2", resFlow: 53, resName: "Rendimiento Hi-Cap Completo", resPhoto: "HighCapseries.png", resHP: 2 },
{ resVal: "35FA2", resFlow: 59, resName: "Rendimiento Hi-Cap Completo", resPhoto: "HighCapseries.png", resHP: 2 }
];이 배열을 다음 두 가지 기준에 따라 정렬하는 함수를 작성해야 합니다.
resFlow 값이 높은 순서(내림차순)로 정렬
resHP 값이 낮은 순서(오름차순)로 정렬
접근 방식
여러 키를 지정된 순서대로 정렬하기 위해 체이닝(chaining) 방식을 활용할 수 있습니다. 즉, 첫 번째 기준으로 비교한 결과가 0이면(두 값이 같으면) 다음 기준으로 비교를 이어가는 방식입니다.
정렬 우선순위는 다음과 같습니다.
resHP 기준 오름차순
resFlow 기준 내림차순
이 방식의 핵심은 델타(delta, 차이값) 계산입니다. 두 객체의 속성 값을 빼서 그 관계를 판단하고, 결과가 0이면 두 값이 같다는 의미이므로 다음 델타를 계산하여 반환합니다. 논리 OR(||) 연산자를 사용하면 첫 번째 비교 결과가 0일 때만 두 번째 비교가 수행되므로 코드가 매우 간결해집니다.
예제 코드
const arr = [
{ resVal: "25FA15", resFlow: 49, resName: "Rendimiento Tri-Seal Completo", resPhoto: "Tri-Sealseries.png", resHP: 1.5 },
{ resVal: "25FA2", resFlow: 52, resName: "Rendimiento Tri-Seal Completo", resPhoto: "Tri-Sealseries.png", resHP: 2 },
{ resVal: "45FA2", resFlow: 53, resName: "Rendimiento Hi-Cap Completo", resPhoto: "HighCapseries.png", resHP: 2 },
{ resVal: "35FA2", resFlow: 59, resName: "Rendimiento Hi-Cap Completo", resPhoto: "HighCapseries.png", resHP: 2 }
];
const sortByTwo = (arr = []) => {
arr.sort((a, b) => {
return a.resHP - b.resHP || b.resFlow - a.resFlow;
});
};
sortByTwo(arr);
console.log(arr);핵심 로직인 a.resHP - b.resHP || b.resFlow - a.resFlow 부분을 자세히 보겠습니다.
a.resHP - b.resHP: resHP를 오름차순으로 비교합니다. 결과가 양수면 b가 앞으로, 음수면 a가 앞으로 옵니다.resHP 값이 같아 결과가 0이면,
b.resFlow - a.resFlow가 평가되어 resFlow를 내림차순으로 비교합니다.
실행 결과
콘솔에 출력되는 결과는 다음과 같습니다.
[
{
resVal: '25FA15',
resFlow: 49,
resName: 'Rendimiento Tri-Seal Completo',
resPhoto: 'Tri-Sealseries.png',
resHP: 1.5
},
{
resVal: '35FA2',
resFlow: 59,
resName: 'Rendimiento Hi-Cap Completo',
resPhoto: 'HighCapseries.png',
resHP: 2
},
{
resVal: '45FA2',
resFlow: 53,
resName: 'Rendimiento Hi-Cap Completo',
resPhoto: 'HighCapseries.png',
resHP: 2
},
{
resVal: '25FA2',
resFlow: 52,
resName: 'Rendimiento Tri-Seal Completo',
resPhoto: 'Tri-Sealseries.png',
resHP: 2
}
]결과를 확인해 보면 resHP가 1.5인 객체가 가장 먼저 배치되고, 나머지 resHP가 2로 같은 객체들은 resFlow 값이 큰 순서(59 → 53 → 52)대로 정렬된 것을 볼 수 있습니다.
마무리
이처럼 Array.prototype.sort()와 논리 OR 연산자를 조합하면 별도의 복잡한 로직 없이도 여러 속성을 기준으로 배열을 손쉽게 정렬할 수 있습니다. 세 개 이상의 속성으로 정렬해야 하는 경우에도 같은 방식으로 비교식을 계속 연결하면 되므로 확장성 또한 뛰어납니다.