정렬

henry·2024년 9월 3일
  • sort()는 JavaScript 내장 메서드로 배열을 정렬하는 기능을 제공합니다.
  • JavaScript에서 배열 객체의 프로토타입 메서드로, 모든 배열은 이 메서드를 상속받아 사용할 수 있습니다.

기본 동작

  • 기본적으로 sort()는 배열의 요소를 문자열로 취급하고 사전식으로 정렬합니다.
  • 예를 들어, [10, 2, 5]를 sort()로 정렬하면 결과는 [10, 2, 5]가 아니라 [10, 5, 2]입니다.
  • 요소들이 문자열로 변환되어 '10', '2', '5'로 비교되기 때문입니다.
const numbers = [10, 2, 5];
numbers.sort();
console.log(numbers); // 출력: [10, 2, 5] (문자열로 정렬)

문자열 비교 방식

  • JavaScript에서 문자열은 각 문자에 대해 유니코드 코드 포인트를 기준으로 비교됩니다.
  • 예를 들어, 문자열 "2", "5", "10"이 있으면, "10"과 "2"를 비교할 때, 첫 번째 문자 "1"과 "2"를 비교합니다.
  • "1"이 "2"보다 작기 때문에 "10"이 "2"보다 앞에 옵니다.

[10, 2, 5] 배열의 문자열 비교

"10"과 "2" 비교:

  • "10"의 첫 번째 문자 '1'의 유니코드 코드 포인트는 U+0031이고,
  • "2"의 첫 번째 문자 '2'의 유니코드 코드 포인트는 U+0032입니다.
  • U+0031(문자 10)이 U+0032(문자 2)보다 작기 때문에, "10"이 "2"보다 앞에 옵니다.

"5"와 "2" 비교:

  • "5"의 첫 번째 문자 '5'의 유니코드 코드 포인트는 U+0035이고,
  • "2"의 첫 번째 문자 '2'의 유니코드 코드 포인트는 U+0032입니다.
  • U+0035가 U+0032보다 크기 때문에, "5"가 "2"보다 뒤에 옵니다.

"10"과 "5" 비교:

  • "10"의 첫 번째 문자 '1'의 유니코드 코드 포인트는 U+0031이고,
  • "5"의 첫 번째 문자 '5'의 유니코드 코드 포인트는 U+0035입니다.
  • U+0031이 U+0035보다 작기 때문에, "10"이 "5"보다 앞에 옵니다.


사용자 정의 비교 함수

숫자나 특정한 기준으로 배열을 정렬하려면 비교 함수를 제공해야 합니다.

비교 함수는 두 개의 인수 a와 b를 받고 다음 값 중 하나를 반환합니다.

  1. 음수 (a < b): a를 b보다 앞에 둡니다.
  2. 양수 (a > b): b를 a보다 앞에 둡니다.
  3. 0 (a === b): a와 b의 순서를 그대로 유지합니다.

예를 들어, 숫자를 오름차순으로 정렬하려면 (a, b) => a - b와 같은 비교 함수를 사용합니다.

const numbers = [10, 2, 5];
numbers.sort((a, b) => a - b);
console.log(numbers); // 출력: [2, 5, 10] (숫자 오름차순으로 정렬됨)

위 코드에서 (a, b) => a - b는 두 숫자의 차이를 계산하여 a가 b보다 크면 양수, 작으면 음수, 같으면 0을 반환합니다.


예시를 통한 설명

[1, 2, 3, 2] 배열을 sort((a, b) => a - b)로 정렬하는 경우,

비교 1

  • 1과 2를 비교.
  • 1 - 2 = -1 (음수) → 순서를 유지.

비교 2

  • 2와 3을 비교.
  • 2 - 3 = -1 (음수) → 순서를 유지.

비교 3

3과 2를 비교.

  • 3 - 2 = 1 (양수) → 위치를 교환하여 2가 3보다 앞에 옵니다.

결과: [1, 2, 2, 3].

여기서 2와 2는 비교할 필요가 없습니다.
a - b = 0인 경우 정렬 알고리즘이 순서를 유지하기 때문에, 추가적인 처리가 필요하지 않습니다.



다양한 방식의 배열 정렬


1. 숫자 오름차순 및 내림차순 정렬

오름차순 정렬

const numbers = [5, 2, 9, 1, 5, 6];
numbers.sort((a, b) => a - b);
console.log(numbers); // 출력: [1, 2, 5, 5, 6, 9]

내림차순 정렬

const numbers = [5, 2, 9, 1, 5, 6];
numbers.sort((a, b) => b - a);
console.log(numbers); // 출력: [9, 6, 5, 5, 2, 1]

2. 문자열 길이에 따른 정렬

const words = ['apple', 'banana', 'kiwi', 'cherry', 'strawberry'];
words.sort((a, b) => a.length - b.length);
console.log(words); // 출력: ['kiwi', 'apple', 'cherry', 'banana', 'strawberry']

3. 객체 배열의 특정 속성에 따른 정렬

const people = [
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 20 },
  { name: 'Charlie', age: 30 }
];

people.sort((a, b) => a.age - b.age);
console.log(people);
// 출력: [{ name: 'Bob', age: 20 }, { name: 'Alice', age: 25 }, { name: 'Charlie', age: 30 }]

특정 속성을 기준으로 정렬하려면 해당 속성의 값을 비교하는 함수를 정의합니다.


4. 알파벳 역순 정렬

const fruits = ['banana', 'apple', 'cherry', 'date'];
fruits.sort((a, b) => b.localeCompare(a));
console.log(fruits); // 출력: ['date', 'cherry', 'banana', 'apple']

5. 대소문자 구분 없이 정렬

const mixedCase = ['banana', 'Apple', 'cherry', 'Date'];
mixedCase.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
console.log(mixedCase); // 출력: ['Apple', 'banana', 'cherry', 'Date']

모든 문자열을 소문자(또는 대문자)로 변환한 뒤 비교합니다.


6. 중첩된 속성에 따른 정렬

const students = [
  { name: 'Alice', grades: { math: 90, english: 85 } },
  { name: 'Bob', grades: { math: 80, english: 95 } },
  { name: 'Charlie', grades: { math: 85, english: 90 } }
];

students.sort((a, b) => a.grades.math - b.grades.math);
console.log(students);
// 출력: [{ name: 'Bob', ... }, { name: 'Charlie', ... }, { name: 'Alice', ... }]

중첩된 객체 속성을 기준으로 정렬하려면 경로를 따라가면서 값을 비교합니다.


7. 다중 기준 정렬

name을 기준으로 먼저 정렬하고, age를 기준으로 두 번째로 정렬

const users = [
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 20 },
  { name: 'Alice', age: 30 },
  { name: 'Bob', age: 25 }
];

users.sort((a, b) => {
  if (a.name === b.name) {
    return a.age - b.age; // 같은 이름이면 나이로 정렬
  } else {
    return a.name.localeCompare(b.name); // 이름으로 정렬
  }
});
console.log(users);
// 출력: [{ name: 'Alice', age: 25 }, { name: 'Alice', age: 30 }, { name: 'Bob', age: 20 }, { name: 'Bob', age: 25 }]

0개의 댓글