프로그래머스의 프론트엔드 과제테스트 중 자바스크립트의 정렬 문제가 나왔다.
여태 진행했던 프로젝트들에선 정렬을 백엔드에서 처리했었기 때문에 조금 당황했다... 이참에 정리해두고자 한다.
❓ Array.prototype.sort()
- Array.prototype.sort() 메서드는 배열의 요소를 제자리에서 정렬하며, 정렬된 배열에 대한 참조를 반환한다.
- 기본적으로 배열의 요소를 문자열로 변환한 후, UTF-16 코드 유닛 값을 기준으로 정렬한다.
▶ 기본 사용 예시
const fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.sort();
console.log(fruits); // ["Apple", "Banana", "Mango", "Orange"]
문자열을 사전 순서로 간단하게 배열하기 좋으나, 숫자를 정렬할 땐 아래와 같이 문제가 발생할 수 있다.
const numbers = [40, 100, 1, 5, 25, 10];
numbers.sort();
console.log(numbers); // [1, 10, 100, 25, 40, 5]
-> 이를 해결하기 위해 비교 함수 사용이 필요하다.
❓ 비교 함수
- 비교 함수는 인접한 두 개의 요소(a, b)를 비교하여 정렬 순서를 결정한다.
- 어떤 알고리즘이 사용되는지는 브라우저 엔진에 따라 다르다.
음수 -> a가 b보다 앞에 위치
0 -> a와 b의 순서를 유지
양수 -> a가 b보다 뒤에 위치
▶ 기본 사용 예시
const numbers = [40, 100, 1, 5, 25, 10];
numbers.sort((a, b) => a - b); // 오름차순
console.log(numbers); // [1, 5, 10, 25, 40, 100]
numbers.sort((a, b) => b - a); // 내림차순
console.log(numbers); // [100, 40, 25, 10, 5, 1]
▶ 객체 배열 사용 예시
const students = [
{ name: "John", age: 25 },
{ name: "Jane", age: 22 },
{ name: "Jack", age: 27 },
];
// 나이 기준 오름차순 정렬
students.sort((a, b) => a.age - b.age);
console.log(students);
// [{ name: "Jane", age: 22 }, { name: "John", age: 25 }, { name: "Jack", age: 27 }]
💥 주의
1️⃣ 제자리 변경
- 원본 배열을 직접 변경하므로, 스프레드 연산자 또는 slice()를 이용해 복사본을 만들어 사용하는 것이 안전하다.
▶ 스프레드 연산자([...])를 이용한 복사 예시 -> 간결하고 직관적!
const originalArray = [3, 1, 4, 1, 5, 9];
const sortedArray = [...originalArray].sort((a, b) => a - b);
console.log("원본 배열:", originalArray); // [3, 1, 4, 1, 5, 9]
console.log("정렬된 배열:", sortedArray); // [1, 1, 3, 4, 5, 9]
▶ slice()를 이용한 복사 예시 -> 오래된 브라우저 호환성 고려시 적합!
const originalArray = [3, 1, 4, 1, 5, 9];
const sortedArray = originalArray.slice().sort((a, b) => a - b);
console.log("원본 배열:", originalArray); // [3, 1, 4, 1, 5, 9]
console.log("정렬된 배열:", sortedArray); // [1, 1, 3, 4, 5, 9]
✅ 추가
만약 정렬 기준이 두 가지인 경우, 이렇게도 사용이 가능하다.
const sortedPosts = [...posts].sort((a, b) => {
if (a.bookmark !== b.bookmark) {
return a.bookmark ? -1 : 1; // 북마크 true가 위로
}
if (orderType === "upload_date") {
return new Date(b.upload_date).getTime() - new Date(a.upload_date).getTime();
} else {
return b.views - a.views;
}
});
인접한 요소들이 bookmark 상태가 다른 경우 = 북마크를 기준으로 정렬되어야 될 요소가 존재할 경우,
bookmark는 boolean이므로 차이로 비교할 수가 없으니, -1과 1을 각각 반환하도록 한다.
이렇게 북마크된 요소들을 맨 앞으로 몰면서, orderType에 따라 정렬한다.
'Javascript' 카테고리의 다른 글
Promise & async & await (0) | 2024.03.01 |
---|---|
Webpack & Babel (0) | 2024.03.01 |
fetch & axios (0) | 2024.03.01 |
ES6 (0) | 2024.03.01 |