JavaScript 배열 정렬: sort() 메서드 완벽 활용 가이드

JavaScript 배열 정렬: sort() 메서드 완벽 활용 가이드 (JavaScript Array Sorting: Mastering the sort() Method)

JavaScript 배열 정렬: `sort()` 메서드 완벽 활용 가이드

JavaScript에서 배열을 정렬하는 것은 매우 흔한 작업입니다. sort() 메서드를 사용하면 간단하게 배열을 정렬할 수 있지만, 문자열과 숫자를 정렬하는 방식에 미묘한 차이가 있어 주의가 필요합니다. 이 가이드에서는 sort() 메서드의 기본적인 사용법부터 복잡한 객체 배열 정렬까지 자세히 다루며, 각 예제에 상세한 주석을 달아 설명해 드립니다.

1. 문자열 배열 오름차순 정렬 (기본 `sort()` 동작)

sort() 메서드는 **기본적으로 배열 요소를 문자열로 변환하여 유니코드(UTF-16) 코드 포인트 값에 따라 오름차순으로 정렬**합니다. 따라서 문자열 배열의 경우, 추가적인 설정 없이도 원하는 결과를 얻을 수 있습니다.


// 과일 이름 문자열 배열 선언
const fruits = ["Banana", "Orange", "Apple", "Mango"];

// fruits 배열을 알파벳 순서(오름차순)로 정렬합니다.
// sort() 메서드는 기본적으로 배열 요소를 문자열로 변환하여 유니코드 값에 따라 정렬합니다.
fruits.sort();

// 정렬된 배열을 콘솔에 출력합니다.
// 예상 출력: ["Apple", "Banana", "Mango", "Orange"]
console.log("문자열 배열 오름차순 정렬:", fruits);
    

2. 숫자 배열 오름차순 정렬 (비교 함수 사용 필수!)

숫자 배열을 sort() 메서드만으로 정렬하면 예상과 다른 결과가 나올 수 있습니다. 예를 들어, [10, 2, 1]을 정렬하면 [1, 10, 2]가 될 수 있는데, 이는 '10'이 '2'보다 '1' 다음에 오기 때문입니다. 숫자 정렬을 위해서는 반드시 **비교 함수(compare function)**를 제공해야 합니다.

오름차순 정렬의 비교 함수: a - b

  • a - b의 결과가 음수면 ab보다 앞에 옵니다.
  • a - b의 결과가 양수면 ba보다 앞에 옵니다.
  • a - b의 결과가 0이면 순서가 변경되지 않습니다.

// 숫자 배열 선언
const numbersAsc = [40, 100, 1, 5, 25, 10];

// numbersAsc 배열을 숫자 값 기준 오름차순으로 정렬합니다.
// sort() 메서드에 비교 함수(compareFunction)를 인자로 전달합니다.
// 이 함수는 배열의 두 요소(a, b)를 비교하여 정렬 순서를 결정합니다.
numbersAsc.sort(function(a, b) {
  // a - b가 음수이면, a가 b보다 작다는 의미이므로 a가 b보다 먼저 위치합니다.
  // a - b가 양수이면, b가 a보다 작다는 의미이므로 b가 a보다 먼저 위치합니다.
  // 결과적으로 작은 숫자가 앞으로 오게 되어 오름차순 정렬이 됩니다.
  return a - b;
});

// 정렬된 배열을 콘솔에 출력합니다.
// 예상 출력: [1, 5, 10, 25, 40, 100]
console.log("숫자 배열 오름차순 정렬:", numbersAsc);
    

3. 숫자 배열 내림차순 정렬 (비교 함수 사용 필수!)

내림차순 정렬 역시 비교 함수를 사용해야 합니다.

내림차순 정렬의 비교 함수: b - a

  • b - a의 결과가 음수면 ba보다 앞에 옵니다.
  • b - a의 결과가 양수면 ab보다 앞에 옵니다.
  • b - a의 결과가 0이면 순서가 변경되지 않습니다.

// 숫자 배열 선언
const numbersDesc = [40, 100, 1, 5, 25, 10];

// numbersDesc 배열을 숫자 값 기준 내림차순으로 정렬합니다.
numbersDesc.sort(function(a, b) {
  // b - a가 음수이면, b가 a보다 작다는 의미이므로 b가 a보다 먼저 위치합니다.
  // b - a가 양수이면, a가 b보다 작다는 의미이므로 a가 b보다 먼저 위치합니다.
  // 결과적으로 큰 숫자가 앞으로 오게 되어 내림차순 정렬이 됩니다.
  return b - a;
});

// 정렬된 배열을 콘솔에 출력합니다.
// 예상 출력: [100, 40, 25, 10, 5, 1]
console.log("숫자 배열 내림차순 정렬:", numbersDesc);
    

4. 객체 배열 정렬: 특정 숫자 속성 기준

객체로 이루어진 배열을 정렬할 때는 객체 내부의 특정 속성(예: age, price, score 등)을 기준으로 정렬해야 합니다. 이때도 숫자 정렬과 마찬가지로 비교 함수를 사용하여 해당 속성 값들을 비교합니다.


// 이름과 나이를 가진 객체들의 배열 선언
const people = [
  { name: "John", age: 30 },
  { name: "Doe", age: 25 },
  { name: "Jane", age: 35 },
  { name: "Peter", age: 25 }
];

// ----------------------------------------------------
// 나이(age) 속성을 기준으로 오름차순 정렬
// ----------------------------------------------------
// people 배열을 각 객체의 'age' 속성 값을 기준으로 오름차순 정렬합니다.
people.sort(function(a, b) {
  // a.age - b.age를 통해 두 객체의 나이를 비교합니다.
  // 결과가 음수이면 a 객체가 b 객체보다 앞에 위치하고, 양수이면 b 객체가 앞에 위치합니다.
  return a.age - b.age;
});
console.log("나이 기준 객체 배열 오름차순 정렬:", people);
/* 예상 출력:
[
  { name: 'Doe', age: 25 },
  { name: 'Peter', age: 25 }, // age가 같을 경우, 초기 순서 유지 (stable sort) 또는 브라우저마다 다를 수 있음
  { name: 'John', age: 30 },
  { name: 'Jane', age: 35 }
]
*/

// ----------------------------------------------------
// 나이(age) 속성을 기준으로 내림차순 정렬
// ----------------------------------------------------
// people 배열을 각 객체의 'age' 속성 값을 기준으로 내림차순 정렬합니다.
people.sort(function(a, b) {
  // b.age - a.age를 통해 두 객체의 나이를 비교합니다.
  // 결과가 음수이면 b 객체가 a 객체보다 앞에 위치하고, 양수이면 a 객체가 앞에 위치합니다.
  return b.age - a.age;
});
console.log("나이 기준 객체 배열 내림차순 정렬:", people);
/* 예상 출력:
[
  { name: 'Jane', age: 35 },
  { name: 'John', age: 30 },
  { name: 'Doe', age: 25 },
  { name: 'Peter', age: 25 }
]
*/
    

5. 객체 배열 정렬: 특정 문자열 속성 기준 (`localeCompare()`)

객체 배열을 문자열 속성(예: name, city 등)을 기준으로 정렬하려면 localeCompare() 메서드를 사용하는 것이 좋습니다. 이 메서드는 **다양한 언어 및 로케일에 따른 문자열 비교를 올바르게 처리**해 주기 때문에, 단순히 <> 연산자를 사용하는 것보다 훨씬 정확합니다.


// 도시 이름과 인구를 가진 객체들의 배열 선언
const cities = [
  { name: "Seoul", population: 9700000 },
  { name: "Busan", population: 3400000 },
  { name: "Jeju", population: 670000 },
  { name: "Daegu", population: 2400000 }
];

// ----------------------------------------------------
// 도시 이름(name) 속성을 기준으로 오름차순 정렬
// ----------------------------------------------------
// cities 배열을 각 객체의 'name' 속성 값을 기준으로 오름차순 정렬합니다.
cities.sort(function(a, b) {
  // a.name.localeCompare(b.name)을 사용하여 두 도시 이름을 비교합니다.
  // localeCompare()는 현재 로케일에 맞는 문자열 비교를 수행하여
  // - 음수: a가 b보다 앞에 와야 함
  // - 양수: b가 a보다 앞에 와야 함
  // - 0: 순서 변경 없음
  // 을 반환합니다.
  return a.name.localeCompare(b.name);
});
console.log("이름 기준 객체 배열 오름차순 정렬:", cities);
/* 예상 출력:
[
  { name: 'Busan', population: 3400000 },
  { name: 'Daegu', population: 2400000 },
  { name: 'Jeju', population: 670000 },
  { name: 'Seoul', population: 9700000 }
]
*/

// ----------------------------------------------------
// 도시 이름(name) 속성을 기준으로 내림차순 정렬
// ----------------------------------------------------
// cities 배열을 각 객체의 'name' 속성 값을 기준으로 내림차순 정렬합니다.
cities.sort(function(a, b) {
  // b.name.localeCompare(a.name)을 사용하여 역순으로 비교합니다.
  return b.name.localeCompare(a.name);
});
console.log("이름 기준 객체 배열 내림차순 정렬:", cities);
/* 예상 출력:
[
  { name: 'Seoul', population: 9700000 },
  { name: 'Jeju', population: 670000 },
  { name: 'Daegu', population: 2400000 },
  { name: 'Busan', population: 3400000 }
]
*/
    

`sort()` 메서드와 비교 함수에 대한 핵심 정리

원본 배열 변경 (In-place sort)

sort() 메서드는 **원본 배열 자체를 변경**합니다. 만약 원본 배열을 유지하면서 정렬된 새로운 배열을 얻고 싶다면, sort()를 호출하기 전에 slice() 메서드를 사용하여 배열의 복사본을 만들어야 합니다.


const originalNumbers = [40, 10, 1];
// slice()를 사용하여 원본 배열의 복사본을 만들고, 그 복사본을 정렬합니다.
const sortedNumbers = originalNumbers.slice().sort((a, b) => a - b);

console.log("원본 배열 (변화 없음):", originalNumbers); // 출력: [40, 10, 1]
console.log("정렬된 새로운 배열:", sortedNumbers);   // 출력: [1, 10, 40]
    

비교 함수의 반환 값 의미

  • compareFunction(a, b)의 반환 값이 **음수**이면, ab보다 **먼저** 와야 합니다.
  • compareFunction(a, b)의 반환 값이 **양수**이면, ba보다 **먼저** 와야 합니다.
  • compareFunction(a, b)의 반환 값이 **0**이면, 두 요소의 상대적인 순서는 **변경되지 않습니다** (하지만 JavaScript 엔진의 구현에 따라 달라질 수 있으므로, 안정적인 정렬을 위해서는 0이 반환되지 않도록 비교 함수를 설계하는 것이 좋습니다).

이 가이드가 여러분의 블로그 게시물에 도움이 되기를 바랍니다! JavaScript 배열 정렬에 대해 더 궁금한 점이 있으시다면 언제든지 질문해주세요.

댓글 없음:

댓글 쓰기

댓글 폭탄 해결! 자바스크립트 댓글 접기/펼치기로 가독성 200% 높이는 법(Solve Comment Chaos: Elevate Readability 200% with JS Comment Folding/Unfolding)

내 웹사이트에 적용! 초간단 자바스크립트 댓글 펼치기/숨기기 튜토리얼 내 웹사이트에 적용! 초간단 자바스크립트 댓글 펼치기/숨기기 튜토...