FrontEnd/HTML5 & CSS & JavaScript

[JavaScript] .map(), .filter(), .reduce() API 비교

푸고배 2022. 1. 18. 22:49

JavaScript의 함수형 프로그래밍은 코드 가독성, 유지 관리 및 테스트에 이점이 있다. 함수형 프로그래밍 사고 방식에 도움이 되는 것 중 하나는 배열 처리 스타일 프로그래밍이다. 배열 처리 스타일 프로그래밍은 배열을 기본 데이터 구조로 사용하며, 배열의 요소에 대한 일련의 작업이 가능하다. 

 

forEach : 배열의 항목에 접근

for 루프는 배열의 모든 항목을 접근, 반복하는데 사용된다.

forEach 역시 같은 역할을 하지만, for문 보다 더 간단하게 접근이 가능하다. 

const strings = ['arielle', 'are', 'you', 'there'];
const capitalizedStrings = [];

for (let i = 0; i < strings.length; i += 1) {
    const string = strings[i];
    capitalizedStrings.push(string.toUpperCase());
}

console.log(capitalizedStrings);
const strings = ['arielle', 'are', 'you', 'there'];
const capitalizedStrings = [];

strings.forEach(function (string) {
    capitalizedStrings.push(string.toUpperCase());
})

console.log(capitalizedStrings);

for 루프를 사용하면 각 배열의 항목에 접근을 하기 위해 인덱스로 접근을 해야하지만, forEach는 배열의 항목을 직접 반환한다.

 

map: 배열을 변환하여 새로운 배열 반환

// 너가 가지고 있는 정보
var officers = [
  { id: 20, name: 'Captain Piett' },
  { id: 24, name: 'General Veers' },
  { id: 56, name: 'Admiral Ozzel' },
  { id: 88, name: 'Commander Jerjerrod' }
];
// 필요한 정보
[20, 24, 56, 88]

만일 위와 같은 예시에서 각 사람의 id 정보만 배열에 담고 싶다면?

forEach를 사용해서 아래와 같이 배열을 초기화 후, push 연산을 사용해서 구현할 수 있다.

var officersIds = [];
officers.forEach(function (officer) {
  officersIds.push(officer.id);
});

하지만, map을 사용하면 아래와 같이 코드를 더 간결하게 작성할 수 있다.

var officersIds = officers.map(function (officer) {
  return officer.id
});

// 화살표 함수(arrow functions) : ES6 지원, Babel 또는 TypeScript 필요
const officersIds = officers.map(officer => officer.id);

map은 callback 함수를 각각의 요소에 대해 한 번씩 순서대로 불러 그 함수의 반환값으로 새로운 배열을 만든다.

arr.map(callback(currentValue[, index[, array]])[, thisArg])

매개변수

  • callback : 새로운 배열 요소를 생성하는 함수. 다음 세가지 인수를 가진다.
    • currentValue : 처리할 현재 요소
    • index(Optional) : 처리할 현재 요소의 인덱스
    • array(Optional) : map()을 호출할 배열
  • thisArg(Optional) : callback을 실행할 때 this로 사용되는 값

반환값

배열의 각 요소에 대해 실행한 callback의 결과를 모은 새로운 배열

 

새로운 결과 값을 반환한 배열은 항상 원래 배열(array)와 동일한 길이이다.

 

filter : 배열의 일부 요소만 추출하여 새로운 배열 반환

만약 배열에서 일부 요소(element)만 존재하는 배열이 필요하다면?

var pilots = [
  {
    id: 2,
    name: "Wedge Antilles",
    faction: "Rebels",
  },
  {
    id: 8,
    name: "Ciena Ree",
    faction: "Empire",
  },
  {
    id: 40,
    name: "Iden Versio",
    faction: "Empire",
  },
  {
    id: 66,
    name: "Thane Kyrell",
    faction: "Rebels",
  }
];

filter를 이용해서 한 배열(array)는 Rebel 파일럿을, 다른 배열(array)에는 Empire 파일럿을 간단하게 구현할 수 있다.

var rebels = pilots.filter(function (pilot) {
  return pilot.faction === "Rebels";
});

var empire = pilots.filter(function (pilot) {
  return pilot.faction === "Empire";
});

// 화살표 함수(arrow functions) : ES6 지원, Babel 또는 TypeScript 필요
const rebels = pilots.filter(pilot => pilot.faction === "Rebels");
const empire = pilots.filter(pilot => pilot.faction === "Empire");

filter는 기본적으로 콜백 함수(callback function)이 true 를 리턴하면 현재 요소(element) 는 결과 배열에 있게 된다. False 를 반환하면 실행되지 않는다.

arr.filter(callback(element[, index[, array]])[, thisArg])

매개변수

  • callback : 각 요소를 시험할 함수. true를 반환하면 요소를 유지하고, false를 반환하면 버린다. 다음 세가지 매개 변수를 받는다.
    • element : 처리할 현재 요소
    • index(Optional) : 처리할 현재 요소의 인덱스
    • array(Optional) : filter를 호출한 배열
  • thisArg(Optional) : callback을 실행할 때 this로 사용하는 값

반환값

테스트를 통과한 요소로 이루어진 새로운 배열. 어떤 요소도 테스트를 통과하지 못했으면 빈 배열을 반환한다.

 

reduce : 배열을 단일 값으로 변환

map과 filter 처럼 redouce 또한 배열의 각 요소(element)에 대해 콜백(callback)을 실행한다. 차이점은 reduce는 this callback(accumulator 누적값)의 결과를 한 배열(array) 요소에서 다른 배열(array)의 요소(element)로 전달한다.

 

accumulator는 거의 모든 것(interger, string, obejct 등)이 될 수 있다.

 

아래와 같이 파일럿 그리고 각 파일럿의 경력 년 수가 담긴 정보를 가진 배열(array)이 있다.

var pilots = [
  {
    id: 10,
    name: "Poe Dameron",
    years: 14,
  },
  {
    id: 2,
    name: "Temmin 'Snap' Wexley",
    years: 30,
  },
  {
    id: 41,
    name: "Tallissan Lintra",
    years: 16,
  },
  {
    id: 99,
    name: "Ello Asty",
    years: 22,
  }
];

reduce를 이용하면 모든 파일럿의 총 경력 년 수를 간단하게 알아볼 수 있다.

var totalYears = pilots.reduce(function (accumulator, pilot) {
  return accumulator + pilot.years;
}, 0);

// 화살표 함수(arrow functions) : ES6 지원, Babel 또는 TypeScript 필요
const totalYears = pilots.reduce((acc, pilot) => acc + pilot.years, 0);
arr.reduce(callback[, initialValue])

매개변수

  • callback : 배열의 각 요소에 대해 실행할 함수. 다음 네 가지 인수를 받는다.
    • accumulator : 누산기는 콜백의 반환값을 누적한다. 콜백의 이전 반환 값 또는, 콜백의 첫 번째 호출이면서 initialValue를 제공한 경우에는 initialValue의 값이다.
    • currentValue : 처리할 현재 요소
    • currentIndex(Optional) : 처리할 현재 요소의 인덱스. initialValue를 제공한 경우 0, 아니면 1부터 시작한다.
    • arrray(Optional) : reduce()를 호출한 배열
  • initialValue(Optional) : callback의 최초 호출에서 첫 번째 인수에 제공하는 값. 초기 값을 제공하지 않으면 배열의 첫 번째 요소를 사용한다. 빈 배열에서 초기값 없이 reduce()를 호출하면 오류가 발생한다.

반환값

누적 계산의 결과 값

 

 

 


Reference

 

How To Use map(), filter(), and reduce() in JavaScript | DigitalOcean

Develop a deeper understanding of functional programming in JavaScript by exploring filter, map, and reduce.

www.digitalocean.com

 

Array.prototype.map() - JavaScript | MDN

map() 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환합니다.

developer.mozilla.org

 

Array.prototype.filter() - JavaScript | MDN

filter() 메서드는 주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환합니다.

developer.mozilla.org

 

Array.prototype.reduce() - JavaScript | MDN

reduce() 메서드는 배열의 각 요소에 대해 주어진 리듀서(reducer) 함수를 실행하고, 하나의 결과값을 반환합니다.

developer.mozilla.org

 

반응형