[javascript] 자바스크립트 배열 정렬 기초, 그리고 숫자를 정렬할 때 주의할 점
자바스크립트의 배열 정렬은 내장 메서드인 sort()를 이용합니다.
sort() 메서드를 이용하면 배열 객체를 간단하게 정렬할 수 있습니다.
그리고, 초보자들에게는 다소 위험한 함정도 포함하고 있습니다.
정렬 기초
sort() 메서드 사용 방법은 간단해서 배열 객체의 메서드로 sort()를 호출하면 객체 요소들이 정렬됩니다.
한글, 영문, 숫자 모두 정렬이 잘 됩니다.
let arrString = ['콘', '라이언', '프로도', '어피치'];
arrString.sort();
console.log(arrString); // ['라이언', '어피치', '콘', '프로도']
let arrNumber = [7, 2, 9, 5];
arrNumber.sort();
console.log(arrNumber); // [2, 5, 7, 9]
sort() 메서드는 기본 호출로는 정순으로만 정렬이 됩니다.
역순으로 정렬하려면 배열의 순서를 뒤집는 sort() 실행 후에 reverse() 메서드를 추가로 호출해서 순서를 뒤집어야 합니다.
let arrString = ['콘', '라이언', '프로도', '어피치'];
arrString.sort().reverse();
console.log(arrString); // ['프로도', '콘', '어피치', '라이언']
숫자를 정렬할 때 주의할 점
sort() 메서드는 정렬 기능을 훌륭하게 수행하지만 문제가 한 가지 있습니다.
다음 숫자 배열 정렬은 전혀 예상치 못한 배열 정렬 결과를 반환합니다.
let arrNumber = [17, 2, 119, 55, 410, 6];
arrNumber.sort();
console.log(arrNumber); // [119, 17, 2, 410, 55, 6]
이렇게 되는 이유는 sort() 메서드가 배열의 요소를 문자열로 판단하기 때문입니다.
앞의 배열을 sort() 메서드는 다음의 배열로 배열 요소를 캐스팅해서 정렬 처리를 합니다.
let arrNumber = ['17', '2', '119', '55', '410', '6'];
문자열로 캐스팅된 숫자는 문자열 정렬 우선 순위에 따라 앞에서부터 작은 문자인 것을 앞쪽으로 정렬하게 됩니다. '119'는 '17' 보다 두 번째 문자가 더 작기 때문에 더 앞에 오게 됩니다.
따라서 sort() 메서드로 숫자 비교를 정확하게 하려면 비교하는 두 요소가 숫자로 캐스팅되도록 해야 합니다.
sort() 메서드는 비교 함수를 인자로 넘길 수 있습니다.
인자로 넘긴 "비교 함수(Compare Function)"는 배열의 두 요소를 비교하는 연산 함수로 사용되며, 배열 요소의 정렬을 결정하는 함수로 사용됩니다.
앞의 숫자 배열은 sort() 메서드에 비교 함수를 인자로 넘겨서 다음과 같이 올바르게 숫자 비교가 되도록 할 수 있습니다.
let arrNumber = [17, 2, 119, 55, 410, 6];
arrNumber.sort((a,b)=>a-b);
console.log(arrNumber); // [2, 6, 17, 55, 119, 410]
자바스크립트의 새로운 문법에 익숙하지 않으면 화살표 함수로 표현한 다음의 비교 함수 단축 표현은
arrNumber.sort((a,b)=>a-b);
다음처럼 별도의 함수로 구현해서 인자로 함수명을 넘길 수도 있습니다.
function sortNumber(a,b){
return a-b;
}
arrNumber.sort(sortNumber);
눈치챘겠지만, 역순으로 정렬하려면 비교 함수의 반환 값이 반대로 되도록 하면 됩니다.
a-b가 아니라 b-a를 하면 역순으로 정렬이 됩니다.
let arrNumber = [17, 2, 119, 55, 410, 6];
arrNumber.sort((a,b)=>b-a);
console.log(arrNumber); // [410, 119, 55, 17, 6, 2]
번거롭게 비교 함수를 인자로 넘겨서 정렬 메서드인 sort()를 구현하는 이유가 또 있습니다. 속도 때문입니다.
sort() 메서드는 데이터 타입 캐스팅을 위한 내부 구조로 인해 약간의 오버헤드가 추가로 있게 됩니다.
비교 함수로 구현한 정렬 방식은 데이터 타입 캐스팅이 단순해지기 때문에 약간의 속도 이득을 볼 수 있습니다.
실제로 숫자로만 구성된 배열을 기준으로 sort() 기본 메서드와 비교 함수 (a, b)=> a-b를 인자로 사용한 sort() 메서드의 정렬 속도는 후자 쪽이 약 10%의 속도 이득이 있습니다.