파일을 이름순으로 정렬하여 관리할 때, 문제가 생겼다.
나중에 만든 ver-10.zip
이 ver-9.zip
보다 앞으로 정렬되기 때문이다.
이러한 버전 숫자를 반영한 정렬 기능을 구현 해야한다.
파일명은 크게 head
, number
, tail
로 나눈다.
head
는 숫자가 아닌 문자로, 한글자 이상이다.number
는 한자리에서 다섯자리 숫자로, 숫자 앞에 0이 올 수 있다.tail
은 그 나머지 부분으로, 아무 글자도 없을 수 있다.파일명을 나누면,
head
를 기준으로 정렬한다. 이 때, 대소문자 구분을 하지 않는다.head
가 같을 때는, number
순으로 정렬한다.head
도 number
도 같을 때는, 기존 순서가 바뀌어선 안된다.우선 파일들을 head, number, tail
로 분리한 객체로 만들어준다.
정규식으로 head
와 number
를 찾고 나머지 부분으로 tail
을 구한다.
head
와 number
가 같을 때, 기존 순서를 유지하기 위해 index
를 담고,
마지막 파일명을 반환하기 편하도록 파일명 file
도 담아준다.
function mapping(files) {
const fileSplit = (file,index)=> {
const reg = /(\D+)(\d+)/;
const [match,head,number] = file.match(reg);
const tail = file.slice(match.length);
return {file,head,number,tail,index};
}
return files.map(fileSplit);
}
function solution(files) {
const filesInMap = mapping(files);
}
이제, 분리한 head, number, index
로 정렬해준다.
head
가 같다면 number
, number
도 같다면 index
로 정렬한다.
js의 sort()
함수는 Stable Sort(정렬 시 기존의 순서가 유지)가 아닐 수 도 있기 때문이다.
function solution() {
const sortHead = (a,b)=> {
const upperA = a.head.toUpperCase();
const upperB = b.head.toUpperCase();
const compare = upperA.localeCompare(upperB);
if(compare == 0) return sortNumber(a,b);
return compare;
}
const sortNumber = (a,b)=> {
const compare = a.number - b.number;
if(compare == 0) return sortIndex(a,b);
return compare;
}
const sortIndex = (a,b)=> a.index - b.index;
return filesInMap.sort(sortHead)
}
마지막으로, 정렬한 배열을 원래의 파일명으로 반환한다.
return filesInMap.sort(sortHead).map(data=>data.file);
function mapping(files) {
const fileSplit = (file,index)=> {
const reg = /(\D+)(\d+)/;
const [match,head,number] = file.match(reg);
const tail = file.slice(match.length);
return {file,head,number,tail,index};
}
return files.map(fileSplit);
}
function solution(files) {
const filesInMap = mapping(files);
const sortHead = (a,b)=> {
const upperA = a.head.toUpperCase();
const upperB = b.head.toUpperCase();
const compare = upperA.localeCompare(upperB);
if(compare == 0) return sortNumber(a,b);
return compare;
}
const sortNumber = (a,b)=> {
const compare = a.number - b.number;
if(compare == 0) return sortIndex(a,b);
return compare;
}
const sortIndex = (a,b)=> a.index - b.index;
return filesInMap.sort(sortHead).map(data=> data.file);
}