HOWTO · TypeScript

TypeScript에서 객체 배열 정렬

이 문서에서는 TypeScript에서 개체 배열을 정렬하는 방법을 보여줍니다.

이 페이지의 내용

employeesList.sort((a, b) => a.empId - b.empId)를 사용하면 타입이 지정된 객체 배열을 정렬할 수 있습니다. 비교 함수는 a를 앞에 두어야 하면 음수를, b를 앞에 두어야 하면 양수를, 비교한 값이 같으면 0을 반환합니다. 내림차순으로 정렬하려면 뺄셈 순서를 바꾸고, 첫 번째 키의 값이 같을 때는 다른 속성을 비교하면 됩니다. sort()는 원본 배열을 변경하므로 원래 순서를 유지해야 한다면 먼저 전개 구문으로 새 배열을 만드세요.

레코드의 객체 타입 정의하기

인터페이스는 각 레코드에 필요한 속성을 정의합니다. 여기서 각 직원은 숫자형 empId와 문자열 empDesignation을 가집니다. 공통 타입을 사용하면 TypeScript가 배열과 비교 함수에서 참조하는 속성 이름을 모두 검사할 수 있습니다. 인터페이스는 컴파일 시점의 계약입니다. 코드를 작성하는 동안 속성 이름의 오타를 찾아내는 데 도움이 되지만, 외부에서 받은 데이터를 런타임에 검증하지는 않습니다. 비교 함수에서 사용하는 값에 맞게 속성 타입을 지정하세요.

TypeScript 객체 배열 만들기

배열을 Employee[]로 선언하면 각 항목이 인터페이스에 맞아야 합니다. TypeScript에서 interface Employee { empId: number; empDesignation: string }를 정의하고 const employeesList: Employee[] = [...]로 선언하세요. 예제에는 empId가 같은 직원이 두 명 있으며, 이들의 직책은 마지막 비교 함수에서 유용한 두 번째 키가 됩니다. 데이터와 정렬 콜백에서 속성 이름을 정확히 일치시켜야 합니다. 각 객체 리터럴은 Employee 타입에 맞는지 검사되므로 필수 속성이 빠졌거나 값의 타입이 잘못되면 타입 검사 중에 오류가 보고됩니다. 아래 실행 예제는 Node.js에서 바로 실행할 수 있도록 JavaScript와 호환되는 객체 리터럴을 사용합니다. TypeScript 타입 주석은 .ts 소스 파일에 작성하세요.

하나 이상의 속성으로 객체 정렬하기

숫자 비교 함수 a.empId - b.empId는 ID를 오름차순으로 정렬하며 값이 같으면 자연스럽게 0을 반환합니다. 내림차순으로 정렬하려면 b.empId - a.empId를 사용하세요. 두 번째 속성으로 정렬하려면 ID 비교 결과가 0이 아닐 때는 그 결과를 반환하고, ID가 같을 때는 empDesignation을 비교하면 됩니다. 두 키가 모두 같은 레코드에는 비교 함수가 0을 반환해야 합니다. 값이 같은 경우마다 -1을 반환하면 정렬 알고리즘에 일관되지 않은 순서 규칙을 줄 수 있습니다. 다른 문자열 필드는 뺄셈 대신 문자열 비교를 사용하세요. 사람의 언어에 맞는 정렬이 필요할 때 localeCompare()를 편리하게 사용할 수 있습니다. 다만 결과가 로캘에 따라 달라질 수 있으므로 지역별로 일관된 순서가 필요하다면 로캘을 명시하세요. 속성이 없을 수도 있다면 값을 비교하기 전에 해당 레코드를 어떤 위치에 둘지 정하고 그 경우를 처리하세요.

다음 예제를 실행해 보세요:

const employeesList = [
  { empId: 20, empDesignation: "senior engineer" },
  { empId: 14, empDesignation: "junior engineer" },
  { empId: 14, empDesignation: "developer" },
  { empId: 25, empDesignation: "program manager" },
  { empId: 12, empDesignation: "director" },
];

const byIdAscending = [...employeesList].sort((a, b) => a.empId - b.empId);
const byIdDescending = [...employeesList].sort((a, b) => b.empId - a.empId);
const byIdThenDesignation = [...employeesList].sort((a, b) =>
  a.empId - b.empId || a.empDesignation.localeCompare(b.empDesignation)
);

console.log(byIdAscending.map((employee) => employee.empId).join(", "));
console.log(byIdDescending.map((employee) => employee.empId).join(", "));
console.log(byIdThenDesignation.map((employee) => `${employee.empId}: ${employee.empDesignation}`).join(" | "));
12, 14, 14, 20, 25
25, 20, 14, 14, 12
12: director | 14: developer | 14: junior engineer | 20: senior engineer | 25: program manager

전개 구문을 사용하면 각 정렬이 복사본을 대상으로 동작하므로 employeesList는 선언한 순서 그대로 유지됩니다. 처음 두 줄은 서로 반대 방향으로 정렬된 ID를 표시합니다. 마지막 줄은 각 ID와 직책을 함께 표시하며, ID가 같은 직원끼리만 직책 비교를 적용합니다. 실제 애플리케이션에서는 같은 값을 가진 레코드의 순서를 정하는 데 의미 있는 보조 속성을 선택하세요. 필요하면 같은 패턴으로 비교를 더 추가할 수 있습니다.