문제 정의
다음과 같은 숫자 배열이 있다고 가정해 보겠습니다.
const arr = [3, 5, 7, 8, 3, 5, 7, 4, 2, 8, 4, 2, 1];
우리가 작성해야 할 함수는 각 요소와 바로 앞에 있는 요소(선행 요소)의 평균값을 순서대로 담은 새로운 배열을 반환하는 함수입니다. 단, 첫 번째 요소는 앞에 위치한 요소가 없기 때문에 그 값 자체를 그대로 결과에 포함합니다.
Array.prototype.map()을 활용한 풀이
이 문제는 Array.prototype.map() 메서드를 활용하면 매우 간결하게 해결할 수 있습니다. map()은 원본 배열을 변경하지 않으면서 각 요소를 변환한 새로운 배열을 만들어 주기 때문에, 이러한 유형의 변환 작업에 특히 적합합니다.
예제 코드
const arr = [3, 5, 7, 8, 3, 5, 7, 4, 2, 8, 4, 2, 1];
const consecutiveAverage = arr => {
return arr.map((el, ind, array) => {
const first = (array[ind-1] || 0);
const second = (1 + !!ind);
return ((el + first) / second);
});
};
console.log(consecutiveAverage(arr));
실행 결과
위 코드를 실행하면 콘솔에 다음과 같은 결과가 출력됩니다.
[ 3, 4, 6, 7.5, 5.5, 4, 6, 5.5, 3, 5, 6, 3, 1.5 ]
코드 동작 원리 살펴보기
핵심 로직은 map() 콜백 함수 내부에 있습니다. 각 부분을 하나씩 분석해 보겠습니다.
array[ind-1] || 0: 현재 인덱스에서 하나 앞의 요소를 가져옵니다. 첫 번째 요소의 경우ind가 0이므로array[-1]은undefined가 되고, 논리 OR 연산자(||)에 의해 0으로 대체됩니다.1 + !!ind: 평균을 구할 때 나눌 개수를 결정합니다.!!ind는 인덱스가 0이면false(숫자로는 0), 그렇지 않으면true(숫자로는 1)로 변환되므로, 첫 번째 요소는 1로 나누고 나머지 요소는 2로 나누게 됩니다.(el + first) / second: 현재 요소와 선행 요소(또는 0)를 더한 뒤, 위에서 계산한 개수로 나누어 최종 평균값을 구합니다.
그 결과, 출력 배열의 첫 번째 값은 원래 값인 3이 그대로 유지되고, 두 번째 값부터는 (현재 요소 + 이전 요소) ÷ 2의 평균이 차례대로 계산됩니다. 예를 들어 두 번째 값은 (5 + 3) ÷ 2 = 4, 세 번째 값은 (7 + 5) ÷ 2 = 6이 됩니다.
for 반복문을 사용한 대안
map() 대신 전통적인 반복문으로도 동일한 결과를 얻을 수 있습니다.
function consecutiveAverage(arr) {
const result = [];
result.push(arr[0]);
for (let i = 1; i < arr.length; i++) {
result.push((arr[i] + arr[i - 1]) / 2);
}
return result;
}
이 방식은 로직이 직관적이라 코드를 처음 보는 사람도 쉽게 이해할 수 있다는 장점이 있습니다. 다만 map()을 활용한 버전이 더 선언적이고 간결하므로, 상황과 팀의 코드 스타일에 맞게 선택하면 됩니다.