배워서 남 주자

배열의 오름차순 정렬과 버스정류장 도착정보표시

미래에서 온 개발자 2022. 10. 19. 18:02

코드를 짜다보면 배열 안의 요소를 오름차순, 내림차순 정렬을 해야 할 일이 종종 생긴다.  

정렬의 동작은 아주 간단하다. sort() 메소드를 써주면 된다. 

 

const arr = [2, 5, 7, 1, 4, 6, 3, 8, 9];
arr.sort();
console.log(arr); // [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

 

하지만 의외로 복병이 숨어 있다. 바로 아래와 같은 경우다. 

 

const array = [13, 7, 49, 2, 5, 91, 8, 63, 15, 1, 24];
array.sort();
console.log(array); // [ 1, 13, 15, 2, 24, 49,  5, 63, 7,  8, 91 ]

 

우리의 상식으로는 [1, 2, 5, 7, 8, 13, 15, 24, 49, 63, 91] 이 나와야 할 것 같은데 그렇지 않은 것이다.

잘 알려져 있다시피 이는 자바스크립트의 sort() 메소드가 문자열의 유니코드에 기반하기 때문이다. 즉 숫자의 크고 작음이 아닌, 숫자를 문자열로 생각해 비교하여 정렬하기 때문에 13, 15가 2보다 앞에 오는 것이다. 

 

 

이걸 처음 배운 날 버스정류장의 도착정보표시 전광판이 이해가 되었다. 

 

출처: 김포신문 (841번 왜 두 개인건데...)

(곧 도착하는 버스 번호가 위에 뜨지 않는 것과 마을버스 등 일반버스가 아닌 버스가 따로 뒤에 나오는 건 차치하고서라도) 우리가 일반적으로 기대하는 버스 안내 정보는 50, 83, 88, 96, 841, 841 순이건만 우리의 기대를 저따구로 배반하는 것이다. 

 

이 문제를 해결하는 건 어려운 일도 아니다. array.sort(); 코드 한 줄을 아래와 같이 대체해 주기만 하면 된다. 

 

array.sort((a, b) => a - b);

 

(왜 이렇게 하면 우리의 기대대로 작동하는지에 대한 설명은 공식 mdn 문서를 참조하도록 하자. 간단히 이해할 수 있는 원리는 아니지만 자바스크립트에 내재된 Tim sort라는 정렬 알고리즘을 사용하여 a와 b 두 값을 비교하고, return 값이 0을 기준으로 0보다 작은지 큰 지에 따라 오름차순, 내림차순 정렬을 한다.)

 

이 간단한 걸 왜 처음부터 적용하지 않았으며, 왜 직후에 개선하지 않았으며, 왜 십수년이 지난 지금까지도 버스정류장에서 문자열 기준으로 오름차순 정렬된 버스번호를 봐야 하는 것인지... 미스테리다. 

 

하지만 프로그래밍을 배우며 이렇게 내 주변 세상의 동작원리를 이해하는 일이 (아직까지는) 무척 즐겁다. 세상을 바라보는 또 하나의 프레임을 얻은 기분이다. 이제 막 첫 발을 뗀 셈이니 앞으로 점점 더 넓어지고 깊어질 일만이 남았다.