문제
두 개의 문자열 str1과 str2를 각각 첫 번째, 두 번째 인수로 받는 JavaScript 함수를 작성해야 합니다.
이 함수는 str1을 str2에 등장하는 문자들의 순서를 기준으로 정렬한 결과를 반환해야 합니다.
예를 들어 함수의 입력이 다음과 같다면,
입력
const str1 = 'coding';
const str2 = 'gncabdi';
출력
const output = 'gncdio';
출력 설명
str2에서 먼저 등장하는 문자일수록 앞쪽에 배치하고, str2에 포함되지 않은 문자들은 가장 뒤에 이어 붙입니다. 위 예제에서는 g → n → c 순서로 정렬된 뒤, str2에 없는 d, i, o가 뒤따르므로 최종 결과는 'gncdio'가 됩니다.
예제 코드
다음은 위 문제를 해결하는 전체 코드입니다.
const str1 = 'coding';
const str2 = 'gncabdi';
const sortByOrder = (str1 = '', str2 = '') => {
str2 = str2.split('');
const arr1 = str1
.split('')
.filter(el => str2.includes(el))
.sort((a, b) => str2.indexOf(a) - str2.indexOf(b));
const arr2 = str1
.split('')
.filter(el => !str2.includes(el));
return arr1.join('') + arr2.join('');
};
console.log(sortByOrder(str1, str2));
출력 결과
gncdio
코드 동작 원리
이 코드의 핵심 로직을 단계별로 살펴보면 다음과 같습니다.
- 기준 순서 배열화: str2를 split('')으로 문자 배열로 변환하여 각 문자의 위치(index)를 손쉽게 참조할 수 있도록 준비합니다.
- 포함 문자 추출 및 정렬: str1의 문자 중 str2에 포함된 것만 filter로 걸러낸 뒤, sort와 indexOf를 활용해 str2의 등장 순서대로 정렬합니다.
- 미포함 문자 처리: str2에 없는 문자들은 별도의 배열(arr2)로 분리하여 원래 순서를 유지한 채 뒤에 붙입니다.
- 결합: 두 배열을 join('')으로 하나의 문자열로 합쳐 최종 결과를 반환합니다.
성능 개선 팁
위 구현은 직관적이지만, includes와 indexOf가 반복 호출되기 때문에 문자열이 매우 길어지면 비효율적일 수 있습니다. 이 경우 Map 객체를 사용해 각 문자의 우선순위를 미리 저장해 두면 조회를 O(1)로 만들 수 있어 전체 성능을 크게 개선할 수 있습니다.