문자열과 숫자가 혼합된 배열이 있을 때, NaN 값이 항상 맨 뒤에 위치하도록 정렬하는 함수를 작성해야 하는 경우가 있습니다. 목표는 일반적인 숫자들이 먼저 나오고, 그다음에 문자열 리터럴이, 마지막에 NaN 값들이 오도록 배열을 정렬하는 것입니다.
여기서 주의할 점이 있습니다. JavaScript에서 NaN의 데이터 타입은 "number"이기 때문에 !number && !string 같은 방식으로는 NaN을 판별할 수 없습니다. 또한 요소의 참/거짓(truthy/falsy) 여부만으로 판단하면 빈 문자열('')도 NaN이나 undefined와 동일한 조건을 만족하게 되어 올바른 정렬이 불가능합니다.
NaN 확인 방법
그렇다면 NaN은 어떻게 확인할 수 있을까요? NaN에는 특별한 성질이 있는데, 바로 자기 자신과도 같지 않다는 점입니다. JavaScript의 다른 모든 값은 value === value 비교에서 true를 반환하지만, 유일하게 NaN === NaN은 항상 false를 반환합니다. 이 특성을 활용하면 배열을 원하는 순서대로 정렬할 수 있습니다.
예제 코드
const arr = [344, 'fd', NaN, '', 5, 'f', 76, NaN, 76, NaN, 87, 89, 'fdf',
23, 'fgg', NaN, 765];
const sorter = (a, b) => {
if(a !== a){
return 1;
}else if(b !== b){
return -1;
}
return typeof a === 'number' ? -1 : 1;
};
arr.sort(sorter);
console.log(arr);정렬 함수의 동작 원리
a !== a가 true라면 a가 NaN이라는 의미이므로 1을 반환해 a를 뒤로 보냅니다.b !== b가 true라면 b가 NaN이므로 -1을 반환해 b를 뒤로 밀어냅니다.- 둘 다 NaN이 아니라면
typeof연산자로 타입을 확인하여 숫자를 문자열보다 앞쪽에 위치시킵니다.
실행 결과
콘솔 출력 결과는 다음과 같습니다.
[
765, 23, 89, 87,
76, 76, 5, 344,
'fd', '', 'f', 'fdf',
'fgg', NaN, NaN, NaN,
NaN
]결과를 보면 숫자들이 가장 앞에, 그다음에 문자열들이, 그리고 NaN 값들이 항상 배열의 맨 뒤에 정렬된 것을 확인할 수 있습니다.