HOWTO · JavaScript

JavaScript에서 속성별로 객체 배열 정렬

이 튜토리얼에서는 속성별로 객체 배열을 정렬하는 방법을 보여줍니다.

이 페이지의 내용

객체 배열을 속성 하나를 기준으로 정렬하려면 sort()에 비교 함수를 전달합니다. 비교 함수는 두 객체에서 해당 속성을 읽고, 첫 번째 객체가 앞에 와야 하면 음수, 뒤에 와야 하면 양수, 두 키가 같으면 0을 반환합니다. 문자열 키에는 문자열 비교를, 숫자 키에는 뺄셈을 사용합니다.

문자열 속성을 기준으로 객체 배열 정렬하기

비교하기 전에 두 문자열을 정규화할 수 있습니다. 이렇게 하면 객체에 저장된 각 lastName 값은 그대로 두면서 대소문자를 구분하지 않고 정렬할 수 있습니다.

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

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

const students = [
  { firstName: 'Rohan', lastName: 'Dalal', age: 19 },
  { firstName: 'Zain', lastName: 'Ahmed', age: 17 },
  { firstName: 'Anadi', lastName: 'Malhotra', age: 19 }
];

students.sort((a, b) => {
  const left = a.lastName.toLowerCase();
  const right = b.lastName.toLowerCase();
  if (left < right) return -1;
  if (left > right) return 1;
  return 0;
});

console.log(students.map(student => student.lastName).join(', '));
Ahmed, Dalal, Malhotra

비교 함수는 sort()가 필요로 하는 정렬 신호를 반환합니다. 정확히 -1이나 1을 반환할 필요는 없으며, 음수·0·양수 중 하나면 됩니다. 대소문자가 정렬 순서에 영향을 주지 않게 하려면 소문자로 바꾸어 비교할 수 있습니다. toLowerCase()는 새 문자열을 반환하므로 객체에 저장된 이름은 바뀌지 않습니다.

localeCompare()로 문자열 정렬하기

문자열 속성에는 간결한 비교 함수를 작성할 수 있고 언어별 정렬 규칙도 고려하는 localeCompare()를 사용할 수 있습니다. 이 메서드는 음수, 0 또는 양수를 반환하므로 sort()에 바로 전달할 수 있습니다.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

const students = [
  { firstName: 'Rohan', lastName: 'Dalal', age: 19 },
  { firstName: 'Zain', lastName: 'Ahmed', age: 21 },
  { firstName: 'Anadi', lastName: 'Malhotra', age: 16 }
];

students.sort((a, b) => a.lastName.localeCompare(b.lastName));
console.log(students.map(student => student.lastName).join(', '));
Ahmed, Dalal, Malhotra

키가 문자열이고 언어별 비교가 적절할 때 이 방법을 선택하세요. localeCompare()는 문자열을 비교하며 숫자 정렬용 메서드는 아닙니다. 언어를 명시하거나 대소문자 구분 같은 옵션을 지정하려면 런타임에서 지원하는 로캘과 옵션을 localeCompare()에 전달하세요.

숫자 속성을 기준으로 정렬하기

첫 번째 객체의 숫자 키에서 두 번째 객체의 숫자 키를 뺍니다. 첫 번째 객체의 나이가 더 적으면 a.age - b.age는 음수가 되어 오름차순에서 a가 b보다 앞에 옵니다.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

const students = [
  { firstName: 'Rohan', lastName: 'Dalal', age: 19 },
  { firstName: 'Zain', lastName: 'Ahmed', age: 21 },
  { firstName: 'Anadi', lastName: 'Malhotra', age: 16 }
];

students.sort((a, b) => a.age - b.age);
console.log(students.map(student => student.age).join(', '));
16, 19, 21

이 뺄셈 방식은 숫자 값에 사용합니다. 이름에는 사용하지 마세요. 문자열을 빼는 것으로는 알파벳순을 나타낼 수 없습니다. 비교 함수를 생략해도 sort()가 객체 속성을 살펴보는 것은 아닙니다. 기본 정렬은 배열 요소를 문자열로 변환한 표현을 비교하므로, 객체를 정렬할 때는 일반적으로 명시적인 비교 함수가 필요합니다.

내림차순으로 정렬하기

비교 함수의 피연산자 순서를 바꾸면 정렬 방향이 뒤집힙니다. 나이를 숫자로 비교할 때 b.age - a.age를 사용하면 나이가 많은 객체가 먼저 옵니다. 이렇게 하면 선택한 속성에 비교 규칙을 적용할 수 있으며, 한 방향으로 정렬한 뒤 결과 배열을 뒤집을 필요가 없습니다.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

const students = [
  { firstName: 'Rohan', lastName: 'Dalal', age: 19 },
  { firstName: 'Zain', lastName: 'Ahmed', age: 21 },
  { firstName: 'Anadi', lastName: 'Malhotra', age: 16 }
];

students.sort((a, b) => b.age - a.age);
console.log(students.map(student => student.age).join(', '));
21, 19, 16

문자열을 내림차순으로 정렬하려면 문자열 비교 결과를 반대로 사용하세요. 예를 들어 a.lastName.localeCompare(b.lastName)에 음수를 취할 수 있습니다. 비교 규칙을 일관되게 유지하여 키가 같은 경우에는 0을 반환하도록 하세요.

sort()의 주요 동작과 한계

sort()는 배열 자체를 변경하고, 변경된 그 배열을 반환합니다. 원래 순서도 유지해야 한다면 먼저 const sortedStudents = [...students]로 배열을 복사한 뒤 복사본을 정렬하세요. 객체 자체는 복제되지 않으므로 배열에서 객체의 위치만 바뀌고 객체의 속성은 바뀌지 않습니다.

비교 함수를 지정하지 않으면 sort()는 값을 문자열로 변환한 다음 그 문자열을 비교합니다. 따라서 기본 정렬은 숫자 순서에 적합하지 않고 객체의 특정 속성을 선택해 정렬하지도 않습니다. 키의 자료형에 맞는 비교 함수를 제공하세요. 이 예제들은 각 객체에 지정한 문자열 또는 숫자 속성이 있다고 가정합니다. 누락된 키나 혼합된 자료형을 처리하는 규칙은 정의하지 않으므로, 그런 데이터를 비교 함수에 전달하기 전에 유효성을 검사하거나 해당 값의 비교 방식을 정하세요.

배열 API에 관한 자세한 내용은 sort() 메서드 참고 자료를 확인하세요.