이번 글에서는 반복되는 요소가 포함될 수 있는 숫자 배열을 입력받아, 배열 안에서 가장 길게 연속으로 반복되는 숫자 시퀀스의 길이를 반환하는 JavaScript 함수를 작성해 보겠습니다.
문제 정의
예를 들어, 다음과 같은 입력 배열이 주어졌다고 가정해 봅시다.
const arr = [2, 1, 1, 2, 3, 3, 2, 2, 2, 1];
이 경우 기대하는 출력값은 3입니다. 숫자 2가 배열 끝부분에서 연속으로 세 번 나타나며, 이것이 배열 전체에서 가장 긴 연속 반복 횟수이기 때문입니다. 참고로 숫자 1은 두 번씩 반복되지만 연속 구간이 더 짧으므로 정답이 될 수 없습니다.
구현 코드
이 문제는 Array.prototype.reduce() 메서드를 두 단계로 활용하면 간결하고 우아하게 해결할 수 있습니다.
const arr = [2, 1, 1, 2, 3, 3, 2, 2, 2, 1];
const findLongestSequence = (arr = []) => {
const res = arr.reduce((acc, val) => {
if(acc.length && acc[acc.length - 1][0] === val){
acc[acc.length - 1].push(val);
}else{
acc.push([val]);
}
return acc;
},[]).reduce((acc, val) => {
return val.length > acc.length ? val : acc;
});
return res.length;
}
console.log(findLongestSequence(arr));
코드 동작 원리
핵심 로직을 단계별로 살펴보면 다음과 같습니다.
- 첫 번째 reduce — 그룹화: 배열을 순회하면서 현재 값(
val)이 바로 앞 하위 배열의 첫 번째 요소와 같으면 해당 하위 배열에 값을 추가하고, 다르면 새로운 하위 배열을 생성합니다. 그 결과 연속된 같은 숫자들이 하나의 하위 배열로 묶입니다. - 두 번째 reduce — 최댓값 탐색: 그룹화된 하위 배열들 중 길이가 가장 긴 배열을 비교 연산을 통해 선택합니다.
- 결과 반환: 최종적으로 선택된 배열의 길이, 즉 가장 긴 연속 반복 시퀀스의 길이를 반환합니다.
실행 결과
위 코드를 실행하면 콘솔에 아래와 같은 결과가 출력됩니다.
3
이처럼 reduce를 활용하면 별도의 카운터 변수 없이도 선언적인 방식으로 연속 반복 시퀀스 문제를 깔끔하게 해결할 수 있습니다.