
문자열 s가 주어질 때, 문자열에서 제일 처음으로 두 번 등장하는 문자를 출력하는 함수를 완성하세요.
만약 두 번 등장하는 문자가 없을 경우 빈 문자열을 반환합니다.
s는 소문자로만 이루어져 있으며, 1 이상 100000 이하의 문자열입니다.
앞서 많이 사용했던 map 함수의 인덱스 값을 이용하면 구할 수 있습니다. 우선 s를 단어별로 쪼갠 후, 각 등장횟수와 함께 map함수에 집어 넣습니다. 어떠한 단어가 두 번 나오게 되면, 정답은 해당 단어가 되며, 반복할 필요가 없으므로 반복문을 중단합니다.
includes를 통해 조금 더 쉽게 구현할 수 있습니다. 만약 해당 단어가 새로 만든 배열 arr에 없다면, 추가하고, 있다면 (2번 이상 나왔다면) 해당 단어를 출력하는 방식입니다.
function solution(s) {
let answer = '';
const charCount = new Map();
for (char of s){
charCount.set(char, (charCount.get(char)|| 0) + 1);
if (charCount.get(char) === 2){
answer = char;
break;
}
}
return answer;
}
위에 작성한 그대로입니다. 단 이전에 풀었던 문제들과 차이점은 forEach대신 for of를 사용했다는 것인데, forEach를 사용하게 되면 break 문을 사용할 수 없어 식이 중단되지 않고, 그렇게 되면 다른 문자가 먼저 나오더라도 무조건 문자의 앞에서부터 2번 이상 나온 단어를 검사하여 출력하기 때문입니다.
function solution(s) {
const arr = [];
return s.split('').find(c => arr.includes(char) ? char : (arr.push(char), false)) || '';
}
find 메서드는 배열에서 주어진 콜백 함수의 조건을 만족하는 첫 번째 요소를 찾아 반환합니다. 만약 조건을 만족하는 요소가 없으면 undefined를 반환합니다.
arr.push(c), false 를 보면 콤마 연산자를 활용하고 있는데, 콤마 연산자는 왼쪽부터 오른쪽으로 표현식을 평가하며, 최종적으로 오른쪽 표현식의 결과를 반환합니다.
//콤마 연산자의 예시
let a = 1;
let b = 2;
let c = (a++, b++, a + b);
console.log(c); //출력: 5
let x = 5;
let y = 10;
let z = (x++, y = x + 2, x + y);
console.log(z); // 출력: 14
따라서 위의 식을 해석하면 이와 같습니다.
s를 나눈 후, 가장 먼저 오는 값을 찾습니다. char은, arr 안에 있다면 char 값을 반환하고, 아니라면 arr에 넣은 후, false를 반환합니다. 만약 모든 문자열을 돌았는데도 중복 값이 없어 false가 나온다면, OR 연산자로 인해 ' ' 값이 반환됩니다.