조금 신기한 자바스크립트의 정렬

오재짱·2021년 8월 5일
2

JavaScript

목록 보기
1/4
post-thumbnail

자바스크립트의 sort()

자바스크립트의 정렬은 조금 특이(?)하게 동작합니다. 다른 언어와 똑같을거라 생각하고 sort 메서드를 사용하면 조금은 당황스러운 상황을 맞이할 수 있습니다.

왜 그런지 정리해보면서 sort에 대해서 궁금했던 점들을 정리해보려고 합니다!

정렬아 너 왜그래...

자바스크립트의 정렬은 정말 신기(?)하게 동작합니다. 만약 다른 언어와 마찬가지로 sort 메서드를 사용하면 아래와 같은 참사가 발생하게됩니다.

const arr = [1, 2, 3, 4, 11];
console.log(arr);

arr.sort();
console.log(arr);



??????????????????????

11이 왜 거기서 나와...?

분명 sort()를 통해 정렬을 시도했지만 뜬금없이 11이 앞으로 나온것을 볼 수 있습니다.

당혹스러운 마음을 가다듬고 sort에 대해서 알아보기 시작했고 MDN 공식 문서에서 답을 찾을 수 있었습니다.

네 ^^ 어쨌든 형변환할게요 ^^

보시는 바와같이 자바스크립트의 sort는 compareFunction, 즉 비교함수를 옵션으로 받을 수 있습니다. 만약 비교 함수를 제공하지 않으면 요소를 문자열로 변환하여 정렬을 진행합니다.

위에 작성했던 코드는 결국 비교 함수가 옵션으로 제공되지 않았기 때문에 정렬을 만나면 아래처럼 문자열로 변환되어 UTF-16 코드 유닛값을 기준으로 정렬되는 것입니다.

const arr = [1, 2, 3, 4, 11]; // 숫자 원소이지만,
arr.sort(); // 비교 함수가 없는 정렬을 만나면
const arr = ['1', '11', '2', '3', '4']; // 문자열로 변환하고 정렬된다.

중요한점은 문자열로 변환하여 정렬을 진행한것이지 정렬 후의 결과값이 문자열이 된다는것은 아닙니다. 간단하게 typeof를 사용해서 확인해보면 아래와 같은 결과를 얻을 수 있습니다.

const arr = [1, 2, 3, 4, 11];
arr.sort();
console.log(arr);
console.log(typeof arr[1]);

만약 문자열의 정렬을 원하는 것이 아니라면 결국 비교 함수가 필요하다는 것을 알 수 있습니다. 그렇다면 비교 함수는 어떻게 작성해야 하고 어떻게 동작하는지도 찾아보게 됬습니다.

형, 변환하지마....

문자열로 형변환되지 않고 정렬을 하기 위해서는 비교 함수를 작성해서 전달해주면 됩니다.
가장 많이 사용되는 비교함수는 아래와 같습니다.

arr.sort((a, b) => a - b); // 오름차순 정렬
arr.sort((a, b) => b - a); // 내림차순 정렬

자바스크립트로 여러 정렬 문제들을 풀어본 분들은 대부분이 알고 있을거라 생각합니다.

하지만 왜 a - b의 경우는 오름차순으로 정렬되는지, b - a의 경우는 내림차순으로 정렬되는지에 대해서는 정확히 알지 못했습니다.

자연스럽게 이에 대한 궁금중이 생겼고 역시나 MDN에서 답을 찾을 수 있었습니다. (킹DN...)

간단히 요약하자면 정렬에 대한 비교 함수가 제공되었을때 정렬 기준은 return 되는 value의 값입니다. value의 값은 아래와 같은 2가지 케이스가 존재합니다.

  1. value가 0보다 큰 경우 (a 앞에 b를 정렬시킨다.)
  2. value가 0보다 작거나 같은 경우 (정렬이 일어나지 않는다.)

결국 0보다 크면 정렬이 일어나고 0보다 작거나 같은 경우에는 정렬이 일어나지 않는다. 라는것이 핵심입니다.

그래서 정렬이 됬구나!

arr.sort((a, b) => a - b); // 오름차순 정렬
arr.sort((a, b) => b - a); // 내림차순 정렬

위와 같은 코드에서 정렬이 됬던 이유는 앞에 있는 a와 뒤에 있는 b를 뺐을때의 value 값 때문이었습니다.

오름차순의 경우 뒤에 있는 원소가 앞에 있는 원소보다 크기 때문에 value 값이 0보다 작거나 같은 경우에 속하게 됩니다. (a - b가 0보다 작으므로 value가 0보다 작거나 같은 경우에 속함)

내림차순의 경우에는 뒤에 있는 원소가 앞에 있는 원소보다 큰 경우 value 값이 0보다 크기 때문에 정렬이 일어나게 됩니다. (b - a가 0보다 크므로 value가 0보다 큰 경우에 속한다.)

고놈 특이하네... 근데... 끌.려

조금은 신비(?)한 자바스크립트의 정렬에 대해서 알아봤습니다. MDN 문서를 통해 정렬에 대해서 알아보고 왜 원하는대로 정렬이 일어나지 않는지, 비교 함수는 어떻게 동작하는지 살펴볼 수 있는 좋은 경험이었습니다.

특이한 자바스크립트 당신....

마음에 들어요...

profile
'설명하지 못하면 이해한게 아니다'라는 마음가짐을 가진 프론트엔드 지망생에서 프론트엔드 개발자가 됬습니당!

1개의 댓글

comment-user-thumbnail
2021년 8월 11일

정말 유쾌하고 쉽게 풀어쓰셨네요! ㅋㅋ

답글 달기