JavaScript로 개발을 하다 보면 배열에서 가장 작은 값의 위치를 찾아야 하는 경우가 자주 있습니다. 이번 글에서는 단순히 하나의 최소값 인덱스를 찾는 것을 넘어, 배열에 최소값이 여러 개 존재할 때 해당 값들의 모든 인덱스를 배열로 반환하는 방법을 알아보겠습니다.
문제 상황
다음과 같은 숫자 배열이 있다고 가정해 보겠습니다.
const arr = [1,2,3,4,1,7,8,9,1];
이 배열에서 가장 작은 요소는 1입니다. 만약 최소값이 하나뿐이라면 아래 코드처럼 간단하게 해결할 수 있습니다.
const min = Math.min.apply(Math, arr); const ind = arr.indexOf(min);
위 코드는 ind를 0으로 설정하며, 최소값이 하나일 때는 정확하게 동작합니다.
최소값이 여러 개일 때의 문제점
하지만 위 예제 배열처럼 최소값 1이 세 번 등장하는 경우에는 어떻게 해야 할까요? indexOf()는 첫 번째로 발견된 인덱스만 반환하기 때문에 나머지 위치를 알 수 없습니다.
우리가 원하는 결과는 최소값이 등장하는 모든 인덱스를 담은 배열, 즉 다음과 같은 출력입니다.
const ind = [0, 4, 8]
해결 방법: reduce와 반복문 활용
먼저 reduce() 메서드를 사용해 배열 전체를 순회하며 최소값을 구한 뒤, 다시 한 번 배열을 순회하면서 최소값과 일치하는 요소의 인덱스를 모두 수집하면 됩니다.
다음은 숫자 배열을 입력받아 최소값의 모든 인덱스를 배열로 반환하는 JavaScript 함수입니다.
const arr = [1,2,3,4,1,7,8,9,1];
const minArray = arr => {
const min = arr.reduce((acc, val) => Math.min(acc, val), Infinity);
const res = [];
for(let i = 0; i < arr.length; i++){
if(arr[i] !== min){
continue;
};
res.push(i);
};
return res;
};
console.log(minArray(arr));코드 동작 원리
1단계: reduce()에 초기값으로 Infinity를 지정하고 Math.min()을 누적 적용하여 배열의 최소값을 구합니다.
2단계: for 반복문으로 배열을 처음부터 끝까지 순회하며, 현재 요소가 최소값과 일치하지 않으면 continue로 건너뜁니다.
3단계: 최소값과 일치하는 요소를 만나면 해당 인덱스를 결과 배열 res에 추가하고, 마지막에 이 배열을 반환합니다.
실행 결과
위 코드를 실행하면 콘솔에 다음과 같은 결과가 출력됩니다.
[ 0, 4, 8 ]
배열에서 세 개의 1이 위치한 인덱스 0, 4, 8이 정확하게 반환되었습니다. 이 방식은 시간 복잡도 O(n)으로 두 번의 선형 순회만 필요하기 때문에 성능 면에서도 효율적이며, 최소값이 몇 개든 상관없이 항상 올바른 결과를 보장합니다.