map, filter, reduce

이하은·2023년 11월 20일

map

기존의 요소 대신 새로운 값으로 반환
콜백 함수를 각 요소를 돌면서 반복 작업을 수행하고, 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열 형태로 얻을때 사용

문법)

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

여기서 콜백함수는 배열의 각 요소에 실행될 함수로, 4가지의 인수를 받는다.

currentValue-처리할 현재 요소

index-처리할 현재 요소의 인덱스

array-map()을 호출한 배열

thisArg-콜백을 실행할 때 this로 사용되는 값

예시 1)

let lengths = ["Michael", "Mary", "Riley"].map(item => item.length);

alert(lengths); // 7,4,5

예시 2)

let numbers = [1, 4, 9];
let roots = numbers.map(Math.sqrt); // roots는 [1, 2, 3]
  • map 함수의 내부 구현을 보다 구체적으로 파악해보기

map함수의 원리를 펼쳐서 적어보면,

function _map(arr, fn) {
 const newArr = [];  // 배열과 콜백함수가 필요.

 for (let i = 0; i < arr.length; i++) {
    const newValue = fn(arr[i]);
    newArr.push(newValue);
  }                 
  // 함수에 arr의 요소들을 arr[i]로 돌면서(i로 arr의 모든 index ) 
     함수에 맞는 반복작업을 수행함. 
     index 0부터 시작하여 arr길이보다 작은 index까지(index는 1가 아닌 0부터 시작하기 때문) 
     계속 반환되는 값을 앞서 선언했던 새 빈 배열에 push해줌.
     
  return newArr;
} 그렇게 되면, 결과적으로 새로운 배열로 반환하게 된다.


ex) const test = [1, 2, 3];
    const result = _map(test, (item) => item * 2);
    console.log(result); // result는 [2, 4, 6]

filter

주어진 배열에서 제공된 함수에 의해 조건에 맞는 요소( 혹은 요소 전체를 담은 배열)를 필터링하여 반환

문법)


filter(callbackFn)
	
조건을 충족하는 요소가 여러 개라면 arr.filter(fn)를 사용

arr.filter(function(item, index, array) // 3개의 인수를 받음

예시)

let users = [
  {id: 1, name: "Max"},
  {id: 2, name: "John"},
  {id: 3, name: "Sarah"}
];

let someUsers = users.filter(item => item.id < 3);

alert(someUsers.length); // 2 (즉, Max와 John 반환)
  • filter 함수의 내부 구현을 보다 구체적으로 파악해보기

filter 함수의 원리를 펼쳐서 적어보면,

function _filter(arr, fn) {  // 배열과 콜백함수가 필요.
  const newArr = [];

  for (let i = 0; i < arr.length; i++) {
    const newValue = fn(arr[i]);
    if(newValue === true) {
      newArr.push(arr[i]);
    } 
    // 함수에 arr의 요소들을 arr[i]로 돌면서 반복작업을 수행함. 
     해당 함수(fn)에 index 0부터 시작하여 arr길이보다 작은 index까지(index는 1가 아닌 0부터 시작하기 때문) 계속 반환되는 값을 넣고, 그 값이 true일 경우에만 앞서 선언했던 새 빈 배열에 push해줌.
  }   return newArr;
      // 그렇게 되면, 결과적으로 함수에 맞는 값들만 새 배열로 반환하게 된다.
} 


ex) 
const test = ['grape', 'banana', 'pineapple'];
const result = _filter(test, (item) => item.length > 6);
console.log(result); // result는 ['banana', 'pineapple'] 

reduce

배열 내 요소를 대상으로 반복 작업하는 매서드 중 하나로, 배열을 기반으로 값 하나를 도출할 때 사용한다는 점에서 find나 map과 차이가 있다.

문법)

arr.reduce(callback[, initialValue]) //아래 4개의 인수를 받음
accumulator – 이전 함수 호출의 결과: 콜백의 이전 반환값 또는, 콜백의 첫 번째 호출이면서 initialValue를 제공한 경우에는 initialValue의 값이 된다.

item – 현재 배열 요소

index – 요소의 위치

array – 배열
  • 첫 번째 인수는 앞서 호출했던 함수들의 결과가 누적되어 저장되는 '누산기(accumulator)'라고 생각하면 된다. 이전 함수 호출 결과는 다음 함수를 호출할 때 첫 번째 인수(previousValue)로 사용된다.
ex)

let arr = [1, 2, 3, 4, 5];

let result = arr.reduce((sum, current) => sum + current, 0);

alert(result); // 15

함수 최초 호출 시,
reduce의 마지막 인수인 0(초깃값)이 sum에 할당된다.
current엔 배열의 첫 번째 요소인 1이 할당된다.
따라서 결과는 1이 된다.

두 번째 호출 시,
sum = 1 이고 여기에 배열의 두 번째 요소(2)가 더해지므로 결과는 3이 된다.

세 번째 호출 시, sum = 3 이고 여기에 배열의 다음 요소가 더해진다.

이런 식의 과정이 계속 반복되며, 마지막 함수까지 호출되면 이 값은 reduce의 반환 값이 된다.

-초깃값이 없으면 reduce는 배열의 첫 번째 요소를 초깃값으로 사용하고 두 번째 요소부터 함수를 호출한다.
-빈 배열에서 초기값 없이 reduce()를 호출하면 오류가 발생하기 때문에 항상 초깃값을 명시해 줄 것을 권장한다.

  • reduce 함수의 내부 구현을 보다 구체적으로 파악해보기

reduce 함수의 원리를 펼쳐서 적어보면,

function _reduce(arr,fn) {  // 배열과 콜백함수가 필요.
  let curr = arr[0]; // arr의 index가 0인 요소를 curr로 만들어주고,

  for (let i = 0; i < arr.length; i++) {
    if (i + 1 === arr.length) {
      break;
    }  
    
    const newValue = fn(curr, arr[i + 1]);
    curr = newValue;
  }  // curr는 현재값이자 누적 값, 처음에는 처음 시작 값. 따라서 초반에 arr[0]으로 만든 것.
       이 값과 그 다음값(arr[i + 1])을 변수로 하여 i를 0부터 i + 1이 arr의 길이와 같아질때까지 
       반복문을 돈다(i+1이 arr의 길이와 같아지면 모든 요소의 반복 작업이 끝난 것). 
       그리고 curr를 newValue로 다시 정의해준다.
       
  return curr;
} // 결과적으로 newValue의 반복 결과가 반환된다.
      
ex)
const test = [1, 4, 2, 3];
const result = _reduce(test, (curr, next) => curr > next ? curr : next);
console.log(result); // result는 4
profile
코(딩)린 벨로그

0개의 댓글