배열의 sort()함수

summereuna🐥·2024년 6월 19일

JS 문법 정리

목록 보기
20/20

1. 배열 정렬: sort(), toSorted()


자바스크립트에서 배열을 정렬할 때는 sort() 함수toSorted() 함수를 사용한다.

1. sort() 함수: 기존 배열을 정렬 후 반환


배열을 상대로 sort() 함수를 호출하면 해당 배열 내의 값들이 오름차순으로 정렬한다.

[3, 1, 2].sort();
// [1, 2, 3]

sort() 함수는 원래 배열 내에 값들을 재배치하며 정렬한 원래 배열을 다시 반환한다.
즉 sort() 함수가 반환한 배열은 sort() 함수를 호출한 원래 배열과 동일하다.

const nums = [3, 1, 2];
const sortedNums = nums.sort();
console.log({ nums, sortedNums });


// {
//   nums: [1, 2, 3],
//   sortedNums: [1, 2, 3]
// }

nums === sortedNums; // true

참고

sort() 함수의 기본 정렬 순서문자열의 유니코드 코드 포인트를 따른다.

  • 따라서 숫자 배열을 정렬 할때, 이런 식으로 뜬다.
//숫자 배열
[100, 3, 1, 20].sort(); // [1, 100, 20, 3]
//음수 포함한 배열
[-3, 2, 0, 1, 3, -2, -1].sort(); // [-1, -2, -3, 0, 1, 2, 3]

2. toSorted() 함수: 배열 사본 정렬해 반환


sort() 함수로 정렬을 할 때 원본 배열을 건드리지 않아야하는 경우에는 반드시 배열을 먼저 복제한 후에 배열 사본을 상대로 정렬을 해야한다.

const nums = [3, 1, 2];
const sortedNums = [...nums].sort(); // 배열 사본 만들기
console.log({ nums, sortedNums });

// {
//   nums: [3, 1, 2],
//   sortedNums: [1, 2, 3]
// }

toSorted() 함수를 사용하면 원본 배열을 건드리지 않고 정렬된 배열 사본을 바로 얻을 수 있다.
toSorted() 함수가 반환한 배열은 원래 배열과 다르다.

const nums = [3, 1, 2];
const sortedNums = nums.toSorted();
console.log({ nums, sortedNums });

// {
//   nums: [3, 1, 2],
//   sortedNums: [1, 2, 3]
// }

nums === sortedNums; // false
  • toSorted() 함수는 인터넷 익스플로러를 제외한 대부분의 모던 브라우저에서 사용이 가능하며, Node.js에서는 v20부터 사용이 가능하다.

2. 숫자 배열 정렬


기본 정렬 순서가 문자열의 유니코드 코드 포인트이기 때문에 숫자를 어떻게 정렬해야 할까라는 고민이 있을 수 있는데, 다행히 배열을 제대로 정렬할 수 있는 방법이 있다.

바로 sort 함수의 매개변수로 compareFunction을 보내는 것이다.

  • arr.sort([compareFunction]);
  • compareFunction: 정렬 순서를 정의하는 함수
    생략하면 배열은 각 요소의 문자열 변환에 따라 각 문자의 유니 코드 코드 포인트 값에 따라 정렬된다.

sort() 함수는 인자로 정렬 기준을 나타내는 콜백 함수를 받는다.
대소비교를 위한 함수에는 2개의 인자가 넘어오며 다음과 같은 규칙을 따라야 한다.

2-1. 첫 번째 인자가 두 번째 인자보다 작으면 음수를 반환

숫자 오름 차순: 첫 번째 인자 - 두번째 인자 (a - b)

[-3, 2, 0, 1, 3, -2, -1].sort((a, b) => a - b);
// [-3, -2, -1, 0, 1,  2,  3]

2-2. 첫 번째 인자가 두 번째 인자보다 크면 양수를 반환

숫자 내림 차순: 두번째 인자 - 첫 번째 인자 (b - a)

[-3, 2, 0, 1, 3, -2, -1].sort((a, b) => b - a);
// [3, 2, 1, 0, -1, -2, -3]

2-3. 첫 번째 인자가 두 번째 인자와 같으면 0을 반환


3. 객체 배열 정렬


const countries = [
  { no: 1, code: "KR", name: "Korea" },
  { no: 2, code: "CA", name: "Canada" },
  { no: 3, code: "US", name: "United States" },
  { no: 4, code: "GB", name: "United Kingdom" },
  { no: 5, code: "CN", name: "China" },
];

3-1. 객체 간 대소 비교 시, 기준을 정해 주지 않는 경우

정렬 기준이 없으므로 기존 배열 그대로 뜬다.
좀 더 엄밀히 얘기하면 자바스크립트에서 객체를 문자열로 변환하면 [object Object]가 되어 배열 내의 모든 객체의 크기가 동일하다고 판단한다.

countries.sort();

console.log(countries);
// [
//     { no: 1, code: 'KR', name: 'Korea' },
//     { no: 2, code: 'CA', name: 'Canada' },
//     { no: 3, code: 'US', name: 'United States' },
//     { no: 4, code: 'GB', name: 'United Kingdom' },
//     { no: 5, code: 'CN', name: 'China' }
//   ]

3-2. 기준을 정해 준 경우

국가 코드 기준으로 정렬을 해보자.
숫자가 아니기 때문에 뺄셈을 하는 대신에 문자열의 localeCompare() 메서드를 사용하여 비교한다.

console.log("a".localeCompare("b")); // -1
console.log("b".localeCompare("a")); // 1
console.log("b".localeCompare("b")); // 0

3-2-1. 문자열의 localeCompare() 메서드를 사용한 오름 차순 정렬

countries.sort((a, b) => a.code.localeCompare(b.code));

console.log(countries);
// [
//   { no: 2, code: 'CA', name: 'Canada' },
//   { no: 5, code: 'CN', name: 'China' },
//   { no: 4, code: 'GB', name: 'United Kingdom' },
//   { no: 1, code: 'KR', name: 'Korea' },
//   { no: 3, code: 'US', name: 'United States' }
// ]

3-2-2. 문자열의 localeCompare() 메서드를 사용한 내림 차순 정렬

countries.sort((a, b) => b.code.localeCompare(a.code));

console.log(countries);
// [
//   { no: 3, code: 'US', name: 'United States' },
//   { no: 1, code: 'KR', name: 'Korea' },
//   { no: 4, code: 'GB', name: 'United Kingdom' },
//   { no: 5, code: 'CN', name: 'China' },
//   { no: 2, code: 'CA', name: 'Canada' }
// ]

4. 다중 기준 정렬


다양한 속성을 가진 사용자들을 담은 배열을

const users = [
  {
    mail: "gregorythomas@gmail.com",
    name: "Brett Holland",
    gender: "M",
    age: 73,
  },
  {
    mail: "hintc12@hotmail.com",
    name: "Madison Martinez",
    gender: "F",
    age: 29,
  },
  {
    mail: "wwagner33@gmail.com",
    name: "Michael Jenkins",
    gender: "M",
    age: 51,
  },
  {
    mail: "ujacksonxejyen@gmail.com",
    name: "Amber Rhodes",
    gender: "F",
    age: 42,
  },
  {
    mail: "daniel7900@gmail.com",
    name: "Karen Rodriguez",
    gender: "F",
    age: 32,
  },
];
  1. 성별을 기준으로 1차 내림차순 정렬하고,

  2. 나이 기준으로 2차 오름차순 정렬을 하려면?

//성별 내림 차순 b-a
users.sort((a, b) => b.gender.localeCompare(a.gender));
//나이 오름 차순 a-b
users.sort((a, b) => a.age - b.age);

//✅ 합치기
//성별 내림 차순 b-a : M > F 순으로
users.sort((a, b) => {
  if (a.gender === b.gender) { // 성별이 같을 경우에는
    return a.age - b.age; //나이 오름 차순(작은것 부터 큰 순서대로) a-b 로 하기
  }
  return b.gender.localeCompare(a.gender);
});


console.log(users); // 동일한 배열에서 작업 수행
// [
//     {
//       mail: 'wwagner33@gmail.com',
//       name: 'Michael Jenkins',
//       gender: 'M',
//       age: 51
//     },
//     {
//       mail: 'gregorythomas@gmail.com',
//       name: 'Brett Holland',
//       gender: 'M',
//       age: 73
//     },
//     {
//       mail: 'hintc12@hotmail.com',
//       name: 'Madison Martinez',
//       gender: 'F',
//       age: 29
//     },
//     {
//       mail: 'daniel7900@gmail.com',
//       name: 'Karen Rodriguez',
//       gender: 'F',
//       age: 32
//     },
//     {
//       mail: 'ujacksonxejyen@gmail.com',
//       name: 'Amber Rhodes',
//       gender: 'F',
//       age: 42
//     }
//   ]

📚 MDN: Array.prototype.sort()
📚 daleseo: 자바스크립트 배열 정렬: sort()와 toSorted() 함수

profile
Always have hope🍀 & constant passion🔥

0개의 댓글