숫자 배열을 입력받아, 현재 요소까지의 누적 합계보다 큰 값만 모아 새로운 배열로 반환하는 JavaScript 함수를 작성해야 합니다. 이 문제는 Array.prototype.reduce() 메서드를 활용해 해결하는 것이 조건입니다.
문제 접근 방식
reduce()는 배열을 순회하면서 하나의 누적값(accumulator)을 유지하는 메서드입니다. 여기서는 누적값을 지금까지 만난 요소들의 합으로 사용하고, 동시에 조건을 만족하는 요소를 결과 배열에 추가하는 방식으로 활용할 수 있습니다.
핵심 로직은 다음과 같습니다.
- 초기 누적값은
0으로 설정합니다. - 각 순회에서 현재 값(
val)이 누적 합계(acc)보다 크면 결과 배열에 push합니다. - 조건 충족 여부와 관계없이 반환값은 항상
acc + val이 되어야 하므로, 콤마 연산자를 사용해 두 작업을 한 표현식에서 처리합니다.
예제 코드
const arr = [1, 2, 30, 4, 5, 6];
const retainGreaterElements = arr => {
let res = [];
arr.reduce((acc, val) => {
return (val > acc && res.push(val), acc + val);
}, 0);
return res;
}
console.log(retainGreaterElements(arr));실행 결과
[1, 2, 30]
동작 과정 상세 분석
위 코드가 어떻게 동작하는지 단계별로 살펴보겠습니다.
| 현재 값(val) | 누적 합계(acc) | val > acc? | 결과 배열(res) | 새 누적값 |
|---|---|---|---|---|
| 1 | 0 | 참 → push | [1] | 1 |
| 2 | 1 | 참 → push | [1, 2] | 3 |
| 30 | 3 | 참 → push | [1, 2, 30] | 33 |
| 4 | 33 | 거짓 | [1, 2, 30] | 37 |
| 5 | 37 | 거짓 | [1, 2, 30] | 42 |
| 6 | 42 | 거짓 | [1, 2, 30] | 48 |
결국 4, 5, 6은 앞선 요소들의 합(33 이상)보다 작기 때문에 제외되고, 최종적으로 [1, 2, 30]만 남게 됩니다.
참고: 가독성을 높인 버전
콤마 연산자를 사용한 표현식은 간결하지만 다소 난해할 수 있습니다. 명시적인 블록 본문을 사용하면 같은 로직을 더 읽기 쉽게 표현할 수 있습니다.
const retainGreaterElements = arr => {
let res = [];
let sum = 0;
arr.reduce((acc, val) => {
if (val > acc) {
res.push(val);
}
return acc + val;
}, 0);
return res;
}두 버전 모두 동일한 결과를 반환하지만, 조건부 로직이 명확히 드러나는 후자의 방식이 협업 환경에서는 더 권장됩니다.