문제: https://programmers.co.kr/learn/courses/30/lessons/17686
리스트로 파일이 주어진다. 숫자가 나오기 전까지 head, 그 뒤 숫자가 number다.
대소문자 관계없이 head를 1차로 정렬하고 그 뒤에 숫자로 정렬한다.
javascript의 sort의 콜백함수에 문자열 먼저 검사 그 후 숫자검사하게 만들어서 해결했다.
sort
안에 콜백함수의 과정을 설명하겠다.
1. 인자로 받은 a,b를 tokenize()
한다. (헤드와 숫자만 추출)
2. sortFile()
: 문자열 비교해서 리턴하고 문자열이 같을 때는 뒤의 number로 비교해서 리턴한다.
tokenize()
file을 돌면서 숫자의 startIndex와 endIndex를 구해서 slice
해주었다.
break
head와 number에 맞게 slice한 뒤에 비교할 수 있게 소문자, 숫자로 변경해준다.
sortFile()
'a'<'b' // true
'ab'<'ac' // true
'ab'>'ac' // false
sort()
는 return이 음수(-) 이면 앞에 양수(-)이면 뒤에 오도록 설계돼 있다.위의 2특징을 이용해 문자(head)먼저 비교해주고 같을 때는 숫자를 빼기(-)해서 return 해준다.
function solution(files) {
files.sort((a, b) => {
const first = tokenize(a);
const second = tokenize(b);
return fileSort(first, second);
});
return files;
}
function tokenize(file) {
let startNumIdx;
let endNumIdx;
for (let i = 0; i < file.length; i++) {
if (!startNumIdx && isNumber(file[i])) {
startNumIdx = i;
}
if (startNumIdx && !isNumber(file[i + 1])) {
endNumIdx = i;
break;
}
}
const head = file.slice(0, startNumIdx);
const num = file.slice(startNumIdx, endNumIdx + 1);
//비교해주기 위해 문자열은 소문자로 숫자string은 숫자로 만들어준다.
return [head.toLowerCase(), num * 1];
}
function isNumber(char) {
return !isNaN(parseInt(char));
}
function fileSort(first, second) {
let [firstHead, firstNum] = first;
let [secondHead, secondNum] = second;
if (firstHead < secondHead) {
return -1;
} else if (firstHead > secondHead) {
return 1;
} else return firstNum - secondNum;
}
중간에 이상한 방법으로 시도를 하려고 해서 시간이 오래 걸린 문제였다.
sort 함수에 대해 검색하고 좀 알아보다가 해결 방법을 생각해냈다.
sort 함수를 이해하고 콜백함수를 유연하게 활용하면 보다 많은 정렬 문제를 쉽게 해결할 수 있을 것 같다는 생각이 들었다.