.reduce 메소드 심화 예시 [자바스크립트]

from0·2020년 12월 6일
0
post-thumbnail

arr.reduce(callback[, initialValue])

  • callback 함수는 배열의 각 요소에 대해 실행하는데 이 때 4가지 인수를 받는다.
    • accumulator : 누산기라고 부르지만 나는 이걸 최신 결과값으로 부른다.
    • current value : 각 항이 된다.
    • index: 각 항의 인덱스를 가리키며 optional하기 때문에 안 쓰는 경우가 많다. 하다보니 쓰고 싶더라 ㅠ
    • array: 이것도 optional. 아직 넣어본 적 없다.
  • InitialValue : acc의 시작값이며 입력하지 않으면 배열의 첫번째 항이 acc가 된다. 각 요소를 그대로 사용하는 경우는 상관없지만, 첫번째 항부터 callback 함수를 적용해야할 경우, initial value를 입력해줘야 한다.

예시 1

var names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];

var countedNames = names.reduce(function (allNames, name) { 
  if (name in allNames) {
    allNames[name]++;
  }
  else {
    allNames[name] = 1;
  }
  return allNames;
}, {});
// countedNames is:
// { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }

배열에 있는 이름이 몇 번 나오는지 세는 문제이다. reduce 메소드의 초기값에 빈 객체 {} 할당하였다. acc 최신 결과값은 allNames 객체다. 키 유무에 따른 조건문으로 처리하였다.

예시 2

var people = [
  { name: 'Alice', age: 21 },
  { name: 'Bob', age: 33 },
  { name: 'Jane', age: 26 },
	{ name: 'Steve', age: 33 },
	{ name: 'Joseph', age: 80 }
];

function groupBy(objectArray, property) {
  return objectArray.reduce(function (acc, obj) {
    var key = obj[property];
    if (!acc[key]) {
      acc[key] = [];
    }
    acc[key].push(obj);
    return acc;
  }, {});
}

var groupedPeople = groupBy(people, 'age');
// groupedPeople is:
// { 
//   21: [
//     { name: 'Alice', age: 21 }, 
//   ], 
//   33: [{ name: 'Bob', age: 33 },
//     { name: 'Steve', age: 33 },
//   ] 
// ...
// }

배열 내 객체는 이름과 나이 속성을 갖는다. 특정 속성으로 그룹 짓고자 할 때 쓰는 함수를 만드는 문제에서 reduce 메소드를 썼다. 역시 초기값으로 빈 객체를 할당해준 뒤 key 유무에 따라 배열 내 요소(객체)를 최신 결과값 객체에 추가한다.

예시 3

var friends = [{
  name: 'Anna',
  books: ['Bible', 'Harry Potter'],
  age: 21
}, {
  name: 'Bob',
  books: ['War and peace', 'Romeo and Juliet'],
  age: 26
}, {
  name: 'Alice',
  books: ['The Lord of the Rings', 'The Shining'],
  age: 18
}];

var allbooks = friends.reduce(function(accumulator, currentValue) {
  return [...accumulator, ...currentValue.books];
}, []);

위 배열의 'books' 속성값을 담은 배열을 출력하는 문제였다. reduce 메소드에 사용된 callback 함수는 .concat 메소드 대신 spread syntax(전개 구문)를 사용하였다.

역시나 초기값은 빈 배열이며, 입력하지 않으면 아래와 같이 뜬다.

accumulator is not iterable. 누산기가 반복 가능하지 않다. 초기값을 설정하지 않으면 배열의 첫번째 요소가 처음 acc(최신 결과값)가 되므로

{
  name: 'Anna',
  books: ['Bible', 'Harry Potter'],
  age: 21
}

해당 객체가 첫번째 acc가 되어 callback 함수의 전개 구문이 동작하지 않는다. 따라서 출력하고자 하는 값이 배열이라면 초기값으로 배열을 넣어줘야한다. <연금술사>를 초기값으로 설정하면 결과에 잘 반영된다.

참조


https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

0개의 댓글