JavaScript에서 배열 내 특정 값이 n번째로 등장하는 위치를 찾아야 하는 경우가 종종 있습니다. 예를 들어, 배열 안에 동일한 구분자가 여러 번 반복될 때 그중 원하는 순서의 위치를 알아내야 할 수 있죠.
이번 글에서는 배열 arr, 문자열 또는 숫자 리터럴 txt, 그리고 숫자 n을 인자로 받는 함수 getIndex()를 작성해 보겠습니다. 이 함수는 txt가 배열 arr에서 n번째로 나타나는 인덱스를 반환하며, 만약 txt가 n번 이상 등장하지 않는다면 -1을 반환해야 합니다.
구현 예제
reduce() 메서드를 활용하면 배열을 한 번만 순회하면서 원하는 값을 효율적으로 찾을 수 있습니다.
const arr = [45, 76, 54, 43, '|', 54, '|', 1, 66, '-', '|', 34, '|', 5, 76];
const getIndex = (arr, txt, n) => {
const position = arr.reduce((acc, val, ind) => {
if (val === txt) {
if (acc.count + 1 === n) {
acc['index'] = ind;
}
acc['count']++;
}
return acc;
}, {
index: -1,
count: 0
});
return position.index;
};
console.log(getIndex(arr, '|', 3));
console.log(getIndex(arr, 54, 2));
console.log(getIndex(arr, '-', 3));실행 결과
콘솔에 출력되는 결과는 다음과 같습니다.
10 5 -1
코드 설명
이 코드의 핵심은 reduce() 메서드입니다. 초기값으로 { index: -1, count: 0 } 객체를 설정하고, 배열의 각 요소를 순회하며 다음과 같이 동작합니다.
- 현재 요소
val이 찾고자 하는 값txt와 일치하면 카운트(count)를 1 증가시킵니다. - 증가된 카운트가 목표 횟수
n과 정확히 일치하는 순간, 해당 요소의 인덱스를index에 저장합니다. - 순회가 끝난 후
index를 반환합니다. 조건을 만족하지 못했다면 초기값인 -1이 그대로 반환됩니다.
예제 결과를 살펴보면, 문자 '|'는 배열에서 총 4번 등장하며 세 번째 등장 위치는 인덱스 10입니다. 숫자 54의 두 번째 등장 위치는 인덱스 5이고, 문자 '-'는 한 번만 등장하므로 세 번째 등장 위치를 요청하면 -1이 반환됩니다.
마무리
이처럼 reduce()를 활용하면 별도의 외부 변수 없이도 깔끔하게 n번째 등장 인덱스를 구할 수 있습니다. 시간 복잡도는 O(n)으로 배열을 한 번만 순회하기 때문에 성능 면에서도 효율적입니다.