javascript의 sort에 대해 알아보자.
Array.sort()
오름차순 : 진행할수록 올라감 ex) 1, 2, 3, 4, 5, ...
내림차순 : 진행할수록 내려감 ex) 7, 6, 5, 6, 3, ...
*진행 방향 : 좌 ➤ 우
OR 상 ➤ 하
Array.sort()는 "배열" 의 요소를 정렬한 후 반환함.
const example = [3, 2, 5, 1, 4];
example.sort();
console.log(example.sort()); // [1, 2, 3, 4, 5]
sort 함수를 사용하면 원본이 수정됨에 주의.
다시 한 번 강조함.
복사본이 만들어지는 것이 아님.따라서 원본 수정을 원치 않을 경우,
간단하게는slice
를 통해 얕은 복사한 후 사용.
const example = [3, 2, 5, 1, 4];
const sortedExample = example.sort();
console.log(sortedExample); // [1, 2, 3, 4, 5]
console.log(example); // [1, 2, 3, 4, 5] - 원본도 수정되어 있음
정렬은
stable sort
가 아닐 수 있음.
기본 정렬 순서는 "문자열"의 "유니코드" 코드 포인트를 따름.
example = [5, 3, 2, 1, 10];
example.sort();
console.log(example); // [1, 10, 2, 3, 5]
우리가 기대한
[1, 2, 3, 5, 10]
과는 다르게[1, 10, 2, 3, 5]
를 반환
💡 인자를 "문자열로 변환" 후 "유니코드"로 비교하기 때문
const months = ["March", "Jan", "Feb", "Dec"];
months.sort();
console.log(months); // ["Dec", "Feb", "Jan", "March"] - 문자열 첫글자의 유니코드 순(알파벳 순)
stable sort
를 위해서는 아래에서 다루는compareFunction
을 설정해야함.
sort 함수 내부에 비교 함수를 작성하여 원하는 조건으로 정렬할 수 있음.
const arr = [5, 3, 2, 1, 10];
// 비교함수 : 오름차순 정렬 (ASC)
arr.sort((a, b) => {
return a - b;
});
console.log("ASC1 : ", arr); // [1, 2, 3, 5, 10]
arr.sort((a, b) => {
if (a > b) return 1;
if (a < b) return -1;
return 0;
});
console.log("ASC2 : ", arr); // [1, 2, 3, 5, 10]
// 비교함수 : 내림차순 정렬 (DESC)
arr.sort((a, b) => {
return b - a;
});
console.log("DESC1 : ", arr); // [10, 5, 3, 2, 1]
arr.sort((a, b) => {
if (a > b) return -1;
if (a < b) return 1;
return 0;
});
console.log("DESC2 : ", arr); // [10, 5, 3, 2, 1]
위 로직에서 유추해보자면,
String type
으로 변환되지 않고 기존의Number type
으로 비교가 되었으며
두 값을 비교해서 return하는 값이 양수인지, 음수인지에 따라 다르게 정렬됨을 알 수 있음.
const arr = [5, 3, 2, 1, 10];
// 비교함수 : 오름차순 정렬 (ASC)
arr.sort((a, b) => {
return a - b;
});
console.log("ASC1 : ", arr); // [1, 2, 3, 5, 10]
- [5, 3]을 비교 함수에 "역순"으로 전달 🚨
a = 3, b = 5
return a - b
=return 3 - 5
=return -2
- return 값이 음수이므로 둘의 위치를 변경(0 또는 양수일 경우 continue)
- 변경된 배열 :
[3, 5, 2, 1, 10]
... 반복
위와 같은 방식으로 반복하여 오름차순으로 정렬.
정리 : 앞/뒤 값을 역순으로 넣고 비교해서
return 값을 음수로 하면 자리를 바꾸고 그렇지 않으면 그대로 둠.
비교 함수에 조건을 추가해서 다중 조건으로 정렬이 가능함.
// 번호, 몸무게, 승률, 우승횟수
const list = [
[1, 60, 33.333333, 3],
[2, 80, 33.333333, 1],
[3, 60, 66.666666, 3],
[4, 80, 66.666666, 2],
[5, 70, 66.666666, 2],
[6, 70, 66.666666, 2],
];
// 정렬 : 승률 높은 순 > 우승횟수 높은 순 > 몸무게 높은순 > 번호 낮은 순
list.sort((a, b) => {
let numA = a[0];
let numB = b[0];
let weightA = a[1];
let weightB = b[1];
let rateA = a[2];
let rateB = b[2];
let countA = a[3];
let countB = b[3];
if (rateA > rateB) return -1;
if (rateA < rateB) return 1;
if (countA > countB) return -1;
if (countA < countB) return 1;
if (weightA > weightB) return -1;
if (weightA < weightB) return 1;
if (numA > numB) return 1;
if (numA < numB) return -1;
return 0;
});
console.log(list);
// 0: [3, 60, 66.666666, 3]
// 1: [4, 80, 66.666666, 2]
// 2: [5, 70, 66.666666, 2]
// 3: [6, 70, 66.666666, 2]
// 4: [1, 60, 33.333333, 3]
// 5: [2, 80, 33.333333, 1]
💡 추가 설명
1. a, b는 역순으로 할당되기 때문에a = 뒤 값
,b = 앞 값
이라는 것에 주의
2. return 값이 음수이면 둘의 자리를 바꿈if (rateA > rateB) return -1; // rateA(뒤)가 rateB(앞) 보다 클 경우 교체 if (rateA < rateB) return 1; // rateA(뒤)가 rateB(앞) 보다 작을 경우 그대로 둠. // 뒤가 앞보다 클 경우에만 자리를 바꿨으므로 최종적으로 앞이 크게 됨 = 내림차순 if (countA > countB) return -1; if (countA < countB) return 1; // 위와 동일 if (weightA > weightB) return -1; if (weightA < weightB) return 1; // 위와 동일 if (numA > numB) return 1; // numA(뒤)가 numB(앞)보다 클 경우 그대로 둠. if (numA < numB) return -1;// numA(뒤)가 numB(앞)보다 작을 경우 교체. // 뒤가 앞보다 작을 경우에만 자리를 바꿨으므로 최정적으로 앞이 작게 됨 = 오름차순
var items = [
{ name: 'Edward', value: 21 },
{ name: 'Sharpe', value: 37 },
{ name: 'And', value: 45 },
{ name: 'The', value: -12 },
{ name: 'Magnetic', value: 13 },
{ name: 'Zeros', value: 37 }
];
// value 기준으로 정렬
items.sort((a, b) => a.value - b.value);
// name 기준으로 정렬
items.sort((a, b) => {
var nameA = a.name.toUpperCase(); // ignore upper and lowercase
var nameB = b.name.toUpperCase(); // ignore upper and lowercase
if (nameA < nameB) return -1;
if (nameA > nameB) return 1;
return 0; // 이름이 같을 경우
});
// name 기준으로 정렬 축약 (upper, lower 판단 필요)
items.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
댓글 환영
질문 환영
by.protect-me