프로그래머스 파일명 정렬 JavaScript
2023년 2월 22일
문제 풀이
HEAD, NUMBER, TAIL로 구성되어 있는 파일들을 정렬하는 문제, 정렬 규칙으로는
- HEAD 부분을 기준으로 사전 순으로 정렬한다. 이때 문자열 비교 시 대소문자 구분을 하지 않는다.
- 파일명의 HEAD 부분이 대소문자 차이 외에는 같을 경우, NUMBER의 숫자순으로 정렬한다. 이때 012와 12는 정렬 시에 같은 값으로 처리한다.(0 무시)
- HEAD, NUMBER 모두 같으면 원래 입력에 주어진 순서를 유지한다.
정렬하기 전, 함수 splitFileName
을 이용해 file을 HEAD, NUMBER, TAIL로 나눈다.
function splitFileName(file)
: file 이름을 [HEAD, NUMBER, TAIL]로 구분 지어 리턴하는 함수, 구분하는 방법은 NUMBER와 TAIL의 시작 인덱스를 찾아 slice
하는 것이다. 이때 TAIL이 빈 문자열인 경우도 생각한다.
- HEAD는 file의 0번부터 NUMBER의 시작 인덱스 이전
file.slice(0, numberIdx)
- NUMBER는 TAIL이 빈 문자열일 경우 NUMBER의 시작 인덱스부터 나머지
file.slice(numberIdx)
, TAIL이 빈 문자열이 아닌 경우 NUMBER의 시작 인덱스부터 TAIL의 시작 인덱스 이전까지file.slice(numberIdx, tailIdx)
- TAIL =
file.slice(tailIdx)
[HEAD, NUMBER, TAIL]로 구분된 file들 files_split
을 규칙에 맞게 정렬한다.
마지막으로 정렬된 files_split
(배열)을 문자열로 join("")
후 리턴.
solution.js
function solution(files) {
const answer = [];
const files_split = [];
files.forEach(file => {
files_split.push(splitFileName(file));
});
files_split.sort((a, b) => {
const a0 = a[0].toUpperCase();
const b0 = b[0].toUpperCase();
if (a0 !== b0) {
if (a0 < b0) {
return -1;
}
if (a0 > b0) {
return 1;
}
return 0;
}
if (a0 === b0) {
if (a[1] !== b[1]) {
return a[1] - b[1];
}
return 0;
}
});
files_split.forEach(file => {
answer.push(file.join(""));
});
return answer;
}
function splitFileName(file) {
let numberIdx = -1;
let tailIdx = -1;
const numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
for (let i = 0; i < file.length; i++) {
if (numbers.includes(file[i]) && numberIdx === -1) {
numberIdx = i;
}
if (numberIdx !== -1 && !numbers.includes(file[i])) {
tailIdx = i;
break;
}
}
const HEAD = file.slice(0, numberIdx);
let NUMBER = '', TAIL = '';
if (tailIdx === -1) {
NUMBER = file.slice(numberIdx);
} else {
NUMBER = file.slice(numberIdx, tailIdx);
TAIL = file.slice(tailIdx);
}
return [HEAD, NUMBER, TAIL];
}