Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

JavaScript에서 대소문자를 구분해 문자열 배열 정렬하기

문제 상황

다음과 같은 문자열 리터럴 배열이 있다고 가정해 보겠습니다.

const arr = ['1185 Design','3 D Exhibits','44Doors', '4Concepts','ABC Data','acceleration'];

이 배열을 제자리(in-place)에서 정렬하는 JavaScript 함수를 작성해야 합니다. 단, 단순한 사전순 정렬이 아니라 다음과 같은 규칙을 따라야 합니다.

  • 특수문자나 숫자로 시작하는 문자열이 가장 앞에 위치합니다.
  • 그 뒤의 문자열들은 알파벳 순서대로 정렬됩니다.
  • 같은 알파벳으로 시작하지만 대소문자가 다른 경우(예: 'a'와 'A'), 소문자로 시작하는 문자열이 먼저 옵니다.

구현 예제

위 조건을 만족하는 코드는 다음과 같습니다.

const arr = ['1185 Design','3 D Exhibits','44Doors', '4Concepts','ABC Data','acceleration'];
const caseSensitiveSort = (arr = []) => {
    const sorter = (a, b) => {
      if (a === b){
          return 0
      };
      if (a.charAt(0) === b.charAt(0)){
          return sorter(a.slice(1), b.slice(1))
      }
      if(a.charAt(0).toLowerCase() === b.charAt(0).toLowerCase()){
          if(/^[a-z]/.test(a.charAt(0)) && /^[A-Z]/.test(b.charAt(0))){
             return -1;
          };
          if(/^[a-z]/.test(b.charAt(0)) && /^[A-Z]/.test(a.charAt(0))){
             return 1;
          };
      };
      return a.localeCompare(b);
    };
    arr.sort(sorter);
}
caseSensitiveSort(arr);
console.log(arr);

실행 결과

콘솔에 출력되는 결과는 다음과 같습니다.

[
    '1185 Design',
    '3 D Exhibits',
    '44Doors',
    '4Concepts',
    'acceleration',
    'ABC Data'
]

코드 동작 원리

핵심은 sorter라는 이름의 재귀 비교 함수입니다. 각 단계의 로직은 다음과 같습니다.

  • 완전히 같은 경우: 두 문자열이 동일하면 0을 반환하여 순서를 유지합니다.
  • 첫 글자가 같은 경우: slice(1)로 첫 글자를 제거한 나머지 부분을 재귀적으로 비교합니다.
  • 대소문자만 다른 경우: 첫 글자를 모두 소문자로 바꿨을 때 같다면, 정규식(/^[a-z]/, /^[A-Z]/)으로 어느 쪽이 소문자인지 판별한 뒤 소문자 쪽이 앞에 오도록 -1 또는 1을 반환합니다.
  • 그 외의 경우: localeCompare()를 사용해 기본적인 사전순 비교를 수행합니다. 이 덕분에 숫자·특수문자가 자연스럽게 알파벳보다 앞에 배치됩니다.

이처럼 비교 함수를 직접 정의하면 기본 sort() 메서드로는 처리하기 까다로운 대소문자 구분 정렬도 손쉽게 구현할 수 있습니다.