JavaScript

[JavaScript] #12 - reduce 함수

yoonddo 2023. 1. 18. 18:00

배열 관련 더 자세한 내용은

[JavaScript] - [JavaScript] #10 - 배열 (Array)

 

[JavaScript] #10 - 배열 (Array)

배열은 같은 자료들을 담는 자료구조 중 하나이다. 객체는 어떤 개체에 대한 정보를 클래스로 틀을 만들고 그 클래스로 여러 개체들에 대한 정보를 담는것으로 배열과는 다르다. 예를들어 객체

yoonddo.tistory.com


자바스크립트의 reduce 함수는 배열의 각 요소를 순회하며 callback 함수의 실행 값을 누적해

하나의 결과값을 반환한다.

arr.reduce(callback[, initialValue])

 

  • callback function
    다음 4가지의 인수를 가진다.
    1. accumulator : accumulator는 callback함수의 반환값을 누적한다.
    2. currentValue : 배열의 현재 요소
    3. index(Optional) : 배열의 현재 요소의 인덱스
    4. array(Optional) : 호출한 배열
    callback 함수의 반환값은 accumulator에 할당되고 순회중 계속 누적되어 최종적으로 하나의
    값을 반환한다.
  • initialValue(Optional)
    최초 callback 함수 실행 시 accumulator 인수에 제공되는 값, 초기값을 제공하지 않을 경우 배열의
    첫 번째 요소를 사용하고 빈 배열에서 초기값이 없을 경우 에러가 발생한다.

반환 값

배열을 순서대로 불러 각 요소에 대해 callback 함수를 실행한 결과를 누적한 겂이다.


예제

배열의 모든 값 (1부터 10까지) 더하기

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

const sum1 = numbers.reduce((accumulator, currentNumber) => accumulator + currentNumber);

console.log('sum1 =', sum1);
// callback함수 선언 후 이용
function sumReducer(accumulator, currentNumber) {
  return accumulator + currentNumber;
}

const sum2 = numbers.reduce(sumReducer);

console.log('sum2 =', sum2);

결과

sum1 = 55

sum2 = 55


오브젝트 배열에서 원하는 항목의 값만 더하기

const peoples = [
  {
    name: '양준혁',
    age: 32,
    job: '야구선수',
    married: false,
  },
  {
    name: '유재석',
    age: 32,
    job: '연예인',
    married: false,
  },
  {
    name: '손흥민',
    age: 32,
    job: '축구선수',
    married: true,
  }
];

// 3명의 나이를 더해봅니다.
// 여기서 초기값 설정이 반드시 필요합니다.
const ageSum = peoples.reduce((accumulator, currentObject) => {
  return accumulator + currentObject.age;
}, 0);

console.log('나이 합 ', ageSum);

결과 96


작동 방식

예제2에서 initialValue를 반드시 넣어줘야 하는 이유는 reduce의 작동 방식과 관련이 있다.

initialValue를 설정했냐 안했냐에 따라 콜백의 최초 호출 시의 accumulator와 currentValue가 달라진다.

 

- initialValue를 설정 한 경우

callback accumulator currentValue currentIndex
1번째 호출 initialValue 배열의 첫번째 요소 0

 

- initialValue를 설정하지 않은 경우

callback accumulator currentValue currentIndex
1번째 호출 배열의 첫번째 요소 배열의 두번째 요소 1

 

예를 들어

const number = [1, 2, 3, 4, 5];

function reducer(accumulator, currentValue, currentIndex) {
  const result = accumulator + currentValue;
  console.log('accumulator = ', accumulator, ', currentValue = ', currentValue, ', currentIndex = ', currentIndex, ', result = ', result);
  return result;
}

// initialValue가 없을 경우
number.reduce(reducer);

// 동작
// accumulator = 1, currentValue = 2, currentIndex = 1, result = 3
// accumulator = 3, currentValue = 3, currentIndex = 2, result = 6
// accumulator = 6, currentValue = 4, currentIndex = 3, result = 10
// accumulator = 10, currentValue = 5, currentIndex = 4, result = 15

// initialValue가 있을 경우
number.reduce(reducer, 0);

// 동작
// accumulator = 0, currentValue = 1, currentIndex = 0, result = 1
// accumulator = 1, currentValue = 2, currentIndex = 1, result = 3
// accumulator = 3, currentValue = 3, currentIndex = 2, result = 6
// accumulator = 6, currentValue = 4, currentIndex = 3, result = 10
// accumulator = 10, currentValue = 5, currentIndex = 4, result = 15

 

initialValue가 없으면 배열의 2번째부터 계산이 시작되는데 배열이 비어있으면 당연히 TypeError가 발생한다.

 

배열의 요소가 하나 뿐이면서 initialValue가 없는 경우, 또는 initialValue는 주어졌으나 배열이 비어 있는 경우엔 계산할 필요가 없기 때문에 그 값을 callback 호출 없이 그대로 반환합니다.

 

위 작동방식을 근거로

예제2번의 경우 initialValue가 없을 경우 첫 번째 콜백에서 TypeError가 발생하게됩니다.

const peoples = [
  {
    name: '양준혁',
    age: 32,
    job: '야구선수',
    married: false,
  },
  {
    name: '유재석',
    age: 32,
    job: '연예인',
    married: false,
  },
  {
    name: '손흥민',
    age: 32,
    job: '축구선수',
    married: true,
  }
];

// initialValue 설정X
const ageSum = peoples.reduce((accumulator, currentObject) => {
  return accumulator + currentObject.age;
});

// 첫번째 콜백 실행
// accumulator = { name: '양준혁', age: 32, job: '야구선수', married: false }
// currentObject = { name: '유재석', age: 32, job: '연예인', married: false }
// currentObject.age = 32
// accumulator + currentObject.age = TypeError

배열에 있는 같은 값의 개수 구하기

const alpha = ['a', 'a', 'a', 'b', 'c', 'c', 'd', 'e'];

const count = alpha.reduce((acc, cur) => {
	if (acc[cur]) {
		acc[cur] += 1;
	} else {
		acc[cur] = 1;
	}
	console.log(acc);
	return acc;
}, {}); // acc를 빈 객체로 초기화 한다.
console.log(count);

//결과 {a: 3, b: 1, c: 2, d: 1, e: 1}

배열에 있는 값 중 10보다 큰 수의 개수 구하기

const numbers1 = [1, 2, 3, 4, 5, 10, 20, 30, 40, 50, 60];

function tenOverNumber(numbers) {
	let count1 = 0;
	numbers1.forEach(n => {
		if (n > 10) {
			count1 += 1;
		}
	});
	return count1;
}
const count1 = tenOverNumber(numbers1);
console.log(count1);
//결과 5

function tenOverNumber2(numbers) {
	return numbers.filter(n => n > 10).length;
};
const count2 = tenOverNumber2(numbers1);
console.log(count2);
//결과 5

function tenOverNumber3(numbers) {
	return numbers.reduce((acc, current) => {
		if (current > 10) {
			return acc + 1;
		} else {
			return acc;
		}
	}, 0);
}
const count3 = tenOverNumber3(numbers1);
console.log(count3);

//결과 5

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

자료 출처 : https://tocomo.tistory.com/26

'JavaScript' 카테고리의 다른 글

[JavaScript] #14 - Class in Javascript  (0) 2023.01.20
[JavaScript] #13 - Prototype  (1) 2023.01.19
[JavaScript] #11 - Math 함수  (0) 2023.01.17
[JavaScript] #10 - 배열 (Array)  (0) 2023.01.14
[JavaScript] #09 - Object.defineProperty()  (0) 2023.01.14