자바스크립트에서 sort 함수는 아래와 같이 사용한다.
array.sort([Compare Function])
이때, 대괄호는 필요에 따라 생략이 가능함을 의미한다.
따라서, Compare Function 없이 sort 함수를 사용할 수 있다.
let arr = [1, 5, 4, 2, 3];
arr.sort();
console.log(arr); // [1,2,3,4,5]
let arr = ['b', 'e', 'd', 'a', 'c'];
arr.sort();
console.log(arr); // ['a', 'b', 'c', 'd', 'e']
한 자리의 숫자 또는 문자열 정렬이 완벽하게 되고 있다.
하지만, 두 자리의 숫자 또는 문자열을 정렬한다면 결과가 어떻게 될까?
let arr = [27, 8, 5, 13];
arr.sort();
console.log(arr);
// 기대 결과: [5, 8, 13, 27]
// 실제 결과: [13, 27, 5, 8]
우리가 기대한 결과는 [5, 8, 13, 27]이지만 실제 결과는 [13, 27, 5, 8] 임을 알 수 있다.
sort 함수는 각 요소를 문자열로 취급하여 정렬을 수행한다.
위 결과에서도 알 수 있듯이 5보다 13이 먼저 온 이유는, 13의 1이 5보다 유니코드에서 앞서기 때문이다.
사전순이라 생각하면 쉽다.
세 글자인 '다람쥐'의 'ㄷ'이 한 글자인 '밥'의 'ㅂ'보다 가나다순으로 앞에 위치하는 것과 같은 원리이다.
따라서, sort 함수를 사용해 제대로 된 정렬을 하기 위해서는 Compare Function(비교함수)을 사용해야 한다.
정렬은 Compare Function의 반환값에 따른다. (<-- 아직 이 부분에 대해서는 왜 이렇게 동작하는지 완전히 이해하지 못해 설명이 조금 부족할 수도 있는 점 양해 바랍니다.)
Compare Function에는 두 개의 인자가 전달되며 반환 값에 대한 해석은 다음과 같다.
- compareFunction(a, b) 리턴 값이 양수인 경우: b가 앞에 위치한다(=a가 더 크다)
- compareFunction(a, b) 리턴 값이 0인 경우: a와 b의 순서를 바꾸지 않는다(=같다)
- compareFunction(a, b) 리턴 값이 음수인 경우: a가 앞에 위치한다(=b가 더 크다)
여기서 Compare Function이 어떻게 동작하는지 좀 더 살펴보기 위해 a, b를 찍어보았는데 조금 의아한 부분이 있다.
let arr = [27, 8, 5, 13];
arr.sort((a, b) => {
console.log(a, b)
});
a b
8 27
5 8
13 5
13 8
13 27
배열의 각 요소들이 순서대로 a, b가 되어 맨 처음에는 당연히 a=27, b=8일 거라 생각했지만, 그와 반대로 a=8, b=27인 것을 볼 수 있었다.
아, a와 b에는 각각 다음 값, 이전 값이 들어가게 되는구나.
그럼 a와 b를 next, prev라고 칭했을 때, 오름차순으로 정렬하는 코드는 이렇게 작성할 수 있다.
// 오름차순으로 정렬
let arr = [27, 8, 5, 13];
arr.sort((next, prev) => {
return next - prev
});
console.log(arr); // [5, 8, 13, 27]
이전 값(prev)이 다음 값(next) 보다 크면 비교 함수의 반환 값은 음수가 된다.
다시 말해, 다음 값이 이전 값보다 작다는 뜻이므로, 다음 값을 앞에 위치시키기 위해 두 값의 순서를 바꾼다.
이 경우에서는 prev=8, next=5를 생각해 보면 된다.
반대로, 내림차순 정렬은 return 문의 next, prev 순서만 바꿔주면 된다.
let arr = [27, 8, 5, 13];
arr.sort((next, prev) => {
return prev - next
});
console.log(arr); // [27, 13, 8, 5]
다음 값(next)이 이전 값(prev) 보다 크면 비교 함수의 반환 값이 음수가 된다.
즉, 이전 값이 다음 값보다 작다는 뜻이므로 다음 값을 앞에 위치시키기 위해 두 값의 순서를 바꾼다.
이 경우에서는 prev=5, next=13인 경우를 생각해 보면 된다.