javascript에서의 정렬에 대하여

·2022년 3월 22일
0

JavaScript

목록 보기
6/13

걍 관심이 계속 가고 툭하면 정렬을 하다보니까 답답해서 걍 적어보려고 한다.
그리고 정렬은 알고리즘의 기본이지만 그만큼 중요하고 어떤 곳에서도 자주 쓰이는 만큼
구조가 어떤식으로 굴러가는지 알아두면 나쁠 것은 없다.

왜? sort를 사용하면 숫자는 정렬이 제대로 되지 않는 것일까?

그건 MDN에 보면 서술이 되어있다. 아래를 사진을 한번 보도록 하자


기본 정렬 순서는 문자열의 유니코드 코드 포인트를 따릅니다.
정렬은 stable sort가 아닐 수도 있습니다.
매개변수에 정의를 따로 하지 않는다면 각 요소는 문자열처리가 되어 유니코드 코드 포인트의 값에 따라 정해집니다.

여기서 유니코드도 중요하지만 단번에 이해되는 사진이 저기 링크를 누르면 나와서 가져왔다.


우리가 숫자를 정렬할 때는 1,20,3,6,67 을 원하는 것이 아니다.
그런데 위 문서의 내용과 사진을 잘 보면
정렬은 Not stable하다는 것과 같은 의미를 가지고 있고.
하트2 스페이드5 하트5 스페이드7의 형태로 정렬이 되어있는 모습을 볼 수 있다.

즉 조건의 한개를 더 거쳐서 판단을 해야하는데 제일 선두에 있는 조건 한개만으로 정렬이 진행된다는 것이다.


그럼 어떤 구조로 되어있길래 저렇게 나오게 되는 것일까?
문서에 나와있는 유니코드란 무엇일까?


유니코드가 뭔지부터 알아보자.

나는 전 세계의 모든 문자를 컴퓨터에서 사용하기 위해 존재하는 산업 표준이다. 라는 거창한 말이 제일 먼저 보인다.

그리고 알고 있는 사람들은 알았겠지만 우리는 언제나 이것을 HTML에서 사용하고 있다.

<meta charset="UTF-8" />
전세계에서 어디서도 보면 언어가 깨지지 않도록 넣는 것이 UTF-8이라는 형식이다.
아무튼 유니코드가 뭔지는 알았고 숫자도 문자열 처리를 하는 과정에서 숫자는 어떤 형식으로 되어있길래
저 모양으로 정렬이 되는지 확인을 해보자.


글 쓰려고 찾다보니 나온 > 유니코드 변환기 < 궁금하면 직접 눈으로 보는 것도 좋다고 생각한다.

위의 사진을 보면 12, 2, 33, 4 총 4개를 입력해서 변환을 했고 띄워쓰기의 간격이 아래 코드창에 보인다.

확인을 해보면
1은 31이란 코드값을 가지고 있고
2는 32 3은 33 4는 34라는 코드값을 가지고 있는 것을 확인할 수 있는데

12는 U+0031U+0032이라는 구조를 확인 할 수 있는데, 결국 .sort()메소드는
제일 앞에 있는 문자열만을 바라보고 값을 정하는 것을 확인할 수 있다.

그리고 여기서 또 잊으면 안되는 맹점이 있는데, 이것은 숫자보다는 문자열의 정렬에 도움이 되는 사진이긴 하지만 알아서 미리 봐서 나쁠 것은 없다.

만약 값이 같을 경우 그 다음 자리수, 거기서도 같을 경우 그 다음 자리수를 비교해서 정렬한다.


그래서? 그럼 숫자는 정렬은 어떻게 해야하는건데?

.sort((a,b)=> a-b) 오름차순
.sort((a,b)=> b-a) 내림차순

왜?

오름차순을 기준으로 할 때 내부에서는 이런 구조가 돌아가고 있다.

let num = [12,2,3,13,4]
num.sort((a,b)=>{return a-b})
num.sort((12,2)=>{return 12-2}) = 10
[2,12,3,13,4]
num.sort((12,3)=>{return 12-3}) = 9
[2,12,12,13,4]
num.sort((2,3)=>{return 2-3}) = -1
[2,3,12,13,4]
num.sort((12,13)=>{return 12-13}) = -1
[2,3,12,13,4]
num.sort((13,4)=>{return 13-4}) = 9
[2,3,12,13,13]
num.sort((12,4)=>{return 12-4}) = 8
[2,3,12,12,13]
num.sort((3,4)=>{return 3-4}) = -1
[2,3,4,12,13]

제일 처음 a에는 최초 값을 가져오고 b는 두번째 값을 가져온다.
그리고 조금 신기한 구조를 확인했는데
a-b를 할 경우에 양수면 b가 제일 앞으로 한칸
a-c를 해도 양수가 된다면 c가 그 앞으로 한칸
b-c를 해서 비교를 한 다음에 양수가 나오면 c를 앞으로 한칸
이 비교를 하는 것이 만약 양수가 계속 나온다면 그 값이 계속 앞으로 한칸씩 이동한다.

그리고 만약 a-b가 음수라면 바로 b-c가 진행되고.... 뭔가 로직이 있는 것 같은데
이거..if문이나 필터로 할 수 있을 것 같은데 이미 완성된 메소드 엎어보려니까 머리가 지끈거린다.....


아무튼 숫자 정렬은 계산이 필요하기에 저 구조를 까먹지말자!


알아두는게 좋은 점

.reverse()는 배열을 그대로 뒤집어주기만 하는 메소드다.
만약 내가 문자열을 순서대로 역정렬을 해주고 싶다면
.sort()를 사용해서 정렬을 해놓고, 그것을 뒤집어서 역정렬을 해야만 원하는 값을 얻을 수 있다.

문자열 정렬이라던가 이것저것 살을 좀 더 붙여놓을 예정이다


참고한 사이트

MDN .sort()
Sorting algorithm
js 시각화

profile
물류 서비스 Backend Software Developer

0개의 댓글