문제 소개
다음과 같은 숫자 배열이 있다고 가정해 보겠습니다.
const array = [3.1, 1, 2.2, 5.1, 6, 7.3, 2.1, 9];
우리는 주어진 숫자를 기준으로, 배열 안의 요소 중 해당 숫자보다 작은 요소와 큰 요소가 각각 몇 개인지 세는 함수를 작성해야 합니다.
예를 들어 기준 숫자가 5.25라면, 다음 5개의 요소는 이 숫자보다 작습니다.
(3.1, 1, 2.2, 5.1, 2.1)
반대로 다음 3개의 요소는 이 숫자보다 큽니다.
(6, 7.3, 9)
참고 − 만약 어떤 요소가 주어진 숫자와 정확히 같다면, 그 요소는 '큰 값(above)'으로 계산합니다.
그럼 이제 이 함수의 코드를 작성해 보겠습니다.
예제 코드
const array = [3.1, 1, 2.2, 5.1, 6, 7.3, 2.1, 9];
const countNumbers = (arr, num) => {
return arr.reduce((acc, val) => {
const legend = ['upper', 'lower'];
const isBelow = val < num;
acc[legend[+isBelow]]++;
return acc;
}, {
lower: 0,
upper: 0
 });
};
console.log(countNumbers(array, 5.25));
console.log(countNumbers(array, 7));
console.log(countNumbers(array, 1));코드 동작 원리
이 코드의 핵심은 reduce() 메서드입니다. 배열을 한 번만 순회하면서 두 개의 카운터를 동시에 관리할 수 있습니다.
legend배열은['upper', 'lower']순서로 선언되어 있습니다.isBelow는 현재 요소가 기준 숫자보다 작은지 판별한 불리언(Boolean) 값입니다.+isBelow는 불리언 값을 숫자로 변환합니다. 즉,false는 0,true는 1이 됩니다.- 따라서 요소가 기준 숫자보다 크거나 같으면 인덱스 0 →
'upper'가 선택되고, 작으면 인덱스 1 →'lower'가 선택됩니다. - 초기 누적 객체는
{ lower: 0, upper: 0 }으로 설정되어 각 조건에 맞는 카운트가 증가합니다.
이처럼 불리언 값을 인덱스로 활용하면 if-else 문 없이도 깔끔하게 분기 처리를 할 수 있다는 점이 이 코드의 매력적인 부분입니다.
출력 결과
콘솔에 출력되는 결과는 다음과 같습니다.
{ lower: 5, upper: 3 }
{ lower: 6, upper: 2 }
{ lower: 0, upper: 8 }첫 번째 결과는 기준값 5.25일 때 작은 요소 5개, 큰 요소 3개임을 보여줍니다. 두 번째는 기준값 7일 때의 결과이며, 세 번째는 기준값 1일 때 모든 요소가 1보다 크므로 lower가 0이 되는 것을 확인할 수 있습니다.