1. sort
let input = ['a','b','A','ddd','C','a7'];
let output = input.sort(); // input = output = ['A','C','a','a7','b','ddd]
sort 함수는 정렬한 후의 결과 배열을 리턴하며, 원본 배열도 같이 수정된다.
매개변수를 생략할 경우 ASCII 문자 표 기준 오름차순으로 정렬된다.
let input = [8,3,5,0,11,6];
let output = input.sort(); // input = output = [0,11,3,5,6,8]
위의 배열을 정렬하면 예상과 다르게 11이 3 보다 앞서있다.
그 이유는 내부적으로 배열의 원소들을 string으로 형변환하고, 이후에 첫 번째 문자를 기준으로 정렬한다.
11의 첫 번째 문자 1이 3보다 아스키 문자표에서 빠르기 때문에 위와 같은 결과가 나온다.
내부적인 정렬 로직을 따르지 않고, 3이 11보다 앞서있도록 정렬하려면 어떻게 해야 할까?
2. CompareFunction
sort 함수에 매개함수 CompareFunction을 넣어주면
배열의 원소 2개를 각각 매개 함수의 인자 a, b로 하여, 매개 함수를 실행하고 그 반환 값을 확인한다.
그리고 반환 값에 따라서 a, b를 정렬한다.
이 과정을 모든 배열의 원소가 1:1로 비교될 때 까지 반복한다. ('배열의 길이!/2' 만큼)
sort 함수가 매개함수의 반환 값을 해석하는 기준은 이러하다.
- 반환 값 < 0 : a가 b보다 앞에 있어야 한다.
- 반환 값 > 0 : a가 b보다 뒤에 있어야 한다.
- 반환 값 == 0 : a와 b의 순서를 바꾸지 않는다.
이 기준을 이용해서 대부분의 정렬을 구현할 수 있다.
(1) number 배열 오름차순 정렬
let input = [8,3,5,0,11,6];
let output = input.sort((a,b) => { return a - b }); // input = output = [0,3,5,6,8,11]
8과 3을 비교하면, 8(a) - 3(b) = 5 이고, 반환 값 5는 0 보다 크기 때문에
sort 함수는 8(a)이 3(b)보다 뒤에 있도록 정렬한다.
(2) number 배열 내림차순 정렬
let input = [8,3,5,0,11,6];
let output = input.sort((a,b) => { return b - a }); // input = output = [11,8,6,5,3,0]
반대로 3(b) - 8(a) = -5는 0보다 작으므로 sort 함수는 8(a)이 3(b)보다 앞에 있도록 정렬한다.
(3) 랜덤 정렬
let input = [1,2,3,4,5,6];
let output = input.sort((a,b) => { return Math.random() - Math.random() }); // input = output = [4,5,1,6,2]
Math.random()은 0부터 1 사이의 랜덤 값을 반환한다.
Math.random() - Math.random()은 -1부터 1까지의 값을 반환하므로 배열을 랜덤으로 정렬시킬 수 있다.
(4) Object 배열 정렬
let fruit = [
{ name : "Apple", price : 300 },
{ name : "Banana", price : 160 },
{ name : "Mango", price : 140 },
{ name : "Cherry", price : 220 }
]
let output = fruit.sort((a,b) => { return a.price - b.price });
number 타입이 아닌, 오브젝트 타입의 원소로 이루어진 배열을 정렬하려면
오브젝트의 number 프로퍼티를 참조해서 정수 타입의 리턴값을 만들고, 정렬할 수 있다.
(5) 조건부 정렬
let fruit = [
{ name : "Apple", price : 300 },
{ name : "Banana", price : 160 },
{ name : "Mango", price : 140 },
{ name : "Cherry", price : 220 }
]
let output = fruit.sort((a,b) => {
if (a.name == "Apple") return -1;
else if (a.name == "Banana") return 1;
if (b.name == "Apple") return 1;
else if (b.name == "Banana") return -1;
});
정수 타입의 프로퍼티에 접근하지 않아도, 리턴값이 정수이기만 하면 된다.
위의 코드를 실행하면 Apple은 배열의 맨 앞에, Banana는 배열의 맨 뒤에 위치하도록 정렬된다.
'JavaScript 기본' 카테고리의 다른 글
함수 리스트 (Delegate) (0) | 2022.04.12 |
---|---|
Array 함수 #6. 기타 (0) | 2022.03.08 |
Array 함수 #4. reduce vs.forEach (0) | 2022.03.02 |
Array 함수 #3. 배열에 원소 추가,삭제 (2) | 2022.02.25 |
Array 함수 #2. 조건 확인 (0) | 2022.02.25 |