[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%의 속도 이득이 있습니다.