문제 상황
실무에서는 다음과 같이 여러 개의 객체를 담고 있는 중첩 배열을 포함한 JSON 객체를 다루는 경우가 매우 흔합니다.
const arr = {
"DATA": [
{
"BookingID": "9513",
"DutyStart": "2016-02-11 12:00:00"
},
{
"BookingID": "91157307",
"DutyStart": "2016-02-11 13:00:00"
},
{
"BookingID": "95117317",
"DutyStart": "2016-02-11 13:30:00"
},
{
"BookingID": "957266",
"DutyStart": "2016-02-12 19:15:00"
},
{
"BookingID": "74",
"DutyStart": "2016-02-11 12:21:00"
}
]
};이제 위와 같은 객체를 인수로 받아, 중첩 배열을 'DutyStart' 속성(날짜) 기준으로 오름차순 또는 내림차순으로 정렬하는 JavaScript 함수를 작성해야 합니다.
해결 방법
핵심은 배열의 sort() 메서드와 Date 객체입니다. 비교 함수 안에서 두 날짜 문자열을 Date 객체로 변환한 뒤 getTime()으로 밀리초 단위 숫자로 바꾸고, 그 차이를 반환하면 날짜순으로 정렬됩니다.
비교 함수가 음수를 반환하면 a가 앞에, 양수를 반환하면 b가 앞에 오기 때문에 a - b는 오름차순, b - a는 내림차순이 됩니다.
예제 코드 (오름차순)
const arr = {
"DATA": [
{ "BookingID": "9513", "DutyStart": "2016-02-11 12:00:00" },
{ "BookingID": "91157307", "DutyStart": "2016-02-11 13:00:00" },
{ "BookingID": "95117317", "DutyStart": "2016-02-11 13:30:00" },
{ "BookingID": "957266", "DutyStart": "2016-02-12 19:15:00" },
{ "BookingID": "74", "DutyStart": "2016-02-11 12:21:00" }
]
};
const sortByDate = arr => {
const sorter = (a, b) => {
return new Date(a.DutyStart).getTime() - new Date(b.DutyStart).getTime();
};
arr["DATA"].sort(sorter);
return arr;
};
console.log(sortByDate(arr));출력 결과
콘솔에는 아래와 같이 날짜가 빠른 순서대로(오름차순) 정렬된 결과가 출력됩니다.
{
DATA: [
{ BookingID: '9513', DutyStart: '2016-02-11 12:00:00' },
{ BookingID: '74', DutyStart: '2016-02-11 12:21:00' },
{ BookingID: '91157307', DutyStart: '2016-02-11 13:00:00' },
{ BookingID: '95117317', DutyStart: '2016-02-11 13:30:00' },
{ BookingID: '957266', DutyStart: '2016-02-12 19:15:00' }
]
}내림차순으로 정렬하려면?
내림차순 정렬은 비교 함수에서 뺄셈 순서만 반대로 바꾸면 됩니다. 즉, b에서 a를 빼주면 최신 날짜가 먼저 오도록 정렬됩니다.
const sorterDesc = (a, b) => {
return new Date(b.DutyStart).getTime() - new Date(a.DutyStart).getTime();
};
arr["DATA"].sort(sorterDesc);알아두면 좋은 팁
Array.prototype.sort()는 원본 배열을 직접 변경(mutation)합니다. 원본 데이터를 그대로 유지해야 한다면 ES2023에서 도입된 toSorted()를 사용하거나, 스프레드 연산자로 복사본을 만든 뒤 정렬하는 것이 안전합니다.
// 원본 유지 방법 1: toSorted() 사용 (ES2023+) const sorted = arr["DATA"].toSorted(sorter); // 원본 유지 방법 2: 복사 후 정렬 const sorted2 = [...arr["DATA"]].sort(sorter);
또한 DutyStart처럼 YYYY-MM-DD HH:mm:ss 형식의 문자열은 대부분의 환경에서 new Date()로 올바르게 파싱되지만, 브라우저 호환성이 걱정된다면 ISO 8601 형식(YYYY-MM-DDTHH:mm:ss)으로 저장하는 것을 권장합니다.