문제 발생
함수 입력으로 들어오는 숫자들을 정렬하려는 상황이었다. [11, 1, 8]을 예를 들어보자. 내가 원하는 대로 정렬을 한다면 결과는 [1, 8, 11]과 같다. Javascript에 배열을 정렬해주는 내장 함수 sort()가 있어서 아무 생각 없이 사용하였다. 그런데 원하는 대로 결과가 잘 나오지 않았다.
let arr = [11, 1, 8];
arr.sort();
console.log(arr); // [1, 11, 8]
왜 그럴까? sort() 함수를 사용할 일은 코딩 테스트뿐만 아니라도 꽤 있을것 같으니 이번 기회에 제대로 알아보려고 한다.
원인
사실 sort() 함수에는 비교 함수를 파라미터로 넣어줄 수 있다. 위 예시에서는 옵션을 아무 것도 주지 않아서 기본 동작대로 실행이 된 것으로 보인다. 그래서 배열의 요소들을 문자열(String) 취급하여 해당 문자의 유니코드 값의 기준에 따라 정렬이 되었다. 즉, sort()의 기본 동작은 배열의 요소를 문자 타입으로 형변환 이후 비교하며 실행된다. 따라서 숫자 값을 정렬하려고 할 때 기본 동작대로 사용하는 것이 아닌 비교 함수를 설정해주어야 한다.
해결 방법
그렇다면 비교 함수를 어떻게 설정해야할까? 우선 기억해야할 것이 있다. 인자가 (a, b)로 주어진 비교 함수에서 반환되는 값이 0보다 작으면 a가 b보다 앞에 있어야 한다. 그리고 반환되는 값이 0보다 크면 b가 a보다 앞에 있어야 하며, 0이 반환된다면 (a = b) 순서를 바꾸지 않는다. 예를 들어보자.
let arr = [11, 1, 8];
arr.sort((a, b) => (b - a));
a는 현재값이고 b는 그 다음 값이다. 순서대로 따라가보자.
1회차
a = 11, b = 1
b - a = 1 - 11 = -10 < 0 (반환값 < 0)
a가 b보다 앞에 있어야 한다.
배열 : [11, 1, 8]
2회차
a = 1, b = 8
b - a = 8 - 1 = 7 > 0 (반환값 > 0)
b가 a보다 앞에 있어야 한다.
배열 : [11, 8, 1]
자 이렇게 비교 함수 (a, b) => b - a 를 파라미터로 넣어준다면 내가 원하는 내림차순으로 배열을 정렬할 수 있다. 이는 마치 버블 정렬과 비슷하지만 sort() 함수의 내부 로직은 훨씬 더 복잡하다고 한다. 어쨌든 나는 지금 좀 더 보기 쉽게 직관적으로 정리할 필요성이 느껴진다.
결론
정렬에 대한 개념과 자료들은 정말 많다. 그것을 모두 다루기에는 전문적인 분야라서 더 깊은 내용은 아직 필요하지 않은 것 같다. 정렬에 대해서 자세히 알고 싶다면 아래 두 사이트가 유용해보인다. 참고하자.
https://visualgo.net/en/sorting
https://algorithm-visualizer.org/brute-force/bubble-sort
Javascript의 sort()를 사용할 때에는 비교 함수를 어떻게 설정하는지에만 관심을 가지면 될 것이다. 아래와 같이 자주 쓰이는 오름차순이나 내림차순은 외워두고 나머지 특수한 상황에서 한정적으로 필요한 비교 함수는 return 값을 생각하며 그때 그때 만들어내는게 좋아보인다.
sort() 비교 함수 정리
- 문자열 정렬 : arr.sort()
- 숫자 오름차순 정렬 : arr.sort((a, b) => a - b)
- 숫자 내림차순 정렬 : arr.sort((a, b) => b - a)
'JavaScript' 카테고리의 다른 글
[npm/yarn] package.json 스크립트 명령어 예시 (0) | 2025.03.17 |
---|---|
[JavaScript] 디바운스와 쓰로틀링 구현하고 활용하기 (0) | 2025.03.17 |
[JavaScript] axios 인터셉터로 전역 에러 처리하기 (0) | 2025.03.17 |
[JavaScript] a 태그의 href="javascript:void(0)"는 무엇인가? - intent scheme (0) | 2022.09.26 |
[JavaScript] DateTime 을 AM/PM 포맷으로 변환하는 법 / AMPM 시간 변환 (0) | 2022.09.16 |