숫자(Number) 또는 문자열(String) 리터럴로 구성된 배열에는 중복된 요소가 포함될 수 있습니다. 이번 글에서는 양의 정수 n을 유일한 인수로 전달받아, 배열 안에서 n번 이상 등장하는 모든 요소를 모아 새로운 배열로 반환하는 함수를 작성해 보겠습니다.
접근 방법
이 문제는 Map() 객체를 활용해 깔끔하게 해결할 수 있습니다. 배열을 순회하면서 각 요소의 등장 빈도를 Map에 기록하고, 지정한 횟수 조건을 만족한 요소만 결과 배열에 담아 반환하는 방식입니다.
예제 코드
const arr = [34, 6, 34, 8, 54, 7, 87, 23, 34, 6, 21, 6, 23, 4, 23];
const moreThan = (arr, num) => {
const creds = arr.reduce((acc, val) => {
let { map, res } = acc;
const count = map.get(val);
if(!count && typeof count !== 'number'){
map.set(val, 1);
}else if(num - count <= 1){
res.push(val);
} else {
map.set(val, count+1);
};
return {map, res};
}, {
map: new Map(),
res: []
});
return creds.res;
};
console.log(moreThan(arr, 3));코드 동작 원리
reduce()메서드로 배열을 순회하며, 누적 객체(accumulator) 안에서 빈도를 저장할Map과 결과를 담을res배열을 함께 관리합니다.- 요소가 처음 등장한 경우, Map에 해당 요소의 빈도를 1로 저장합니다.
- 현재 빈도와 목표 횟수
num의 차이가 1 이하라면, 즉 요소가 n번째 등장한 시점이라면 결과 배열에 추가합니다. - 그 외의 경우에는 Map에 기록된 빈도 값을 1씩 증가시킵니다.
실행 결과
위 코드를 실행하면 콘솔에 다음과 같이 출력됩니다.
[34, 6, 23]
배열 arr에서 34, 6, 23은 각각 세 번 이상 등장하기 때문에 최종 결과 배열에 포함되고, 나머지 요소들은 제외됩니다. 이처럼 Map과 reduce()를 조합하면 별도의 반복문 없이도 요소 빈도 기반 필터링 로직을 간결하게 구현할 수 있습니다.