Javascript

배열 반복문 3인방 ( filter(), map(), reduce() )

becky(지은) 2023. 3. 14. 23:22

고차함수란?
1. 전달인자로 함수를 받는 함수
2. 함수를 리턴하는 함수
둘 중에 하나 이상 해당되면 고차함수이다.
 
고차함수에서 자주 쓰이는 내장고차함수 3가지 메소드가 있다.
특히, 배열 반복문에서 자주쓰이는 3인방이다. 그래서 배열 반복문 3인방이라고 이름 짓겠다.


 

 
 
 
 
 
 

arr.filter()

 
특정 기준을 가지고 분류할때 (필터링)
- 여러 음료중에서 티 종류만 꺼내고 싶을때 (티 종류만으로 배열만들기)
 
리턴값이 '참'인것만 걸러진다.

문제 : 문자열을 요소로 갖는 배열을 입력받아 그 길이가 홀수인 요소만을 갖는 배열을 리턴해야 합니다.
function filterOddLengthWords(words) {
  // TODO: 여기에 코드를 작성합니다.
  return words.filter(function(el){
  if(el.length %2 === 1){
    return true;
  }
  return false;
  })
}

 
 
 
 
 
 
 

arr.map()

 

 

특정 속성값을 새로운 배열로 반환할때
- 4개 노트북에 대응되는 브랜드 정보를 확인할때 (4개의 브랜드들로 배열만들기)

문제 : 개인 정보를 담고 있는 객체를 요소로 갖는 배열을 입력받아 각 객체의 'name' 속성을 요소로 갖는 배열을 리턴해야 합니다.
function getOnlyNames(arr) {
  // TODO: 여기에 코드를 작성합니다.
  return arr.map(function(el){
    return el.name;
  })
}

//console.log(output); // --> ['Harry', 'Ron', 'Hermione']


// el이 가리키는 것은  객체의 각 요소 (아래는 3가지 예시의 el)
// { name: 'Harry', age: 15 }
// { name: 'Ron', age: 14 }
// { name: 'Hermione', age: 14 }

 
 

arr.filter() 과 arr.map() 혼합버전
문제: 개인 정보를 담고 있는 객체를 요소로 갖는 배열을 입력받아 18세 이상인 사람의 이름을 요소로 갖는 배열을 리턴해야 합니다.
function getOnlyAllowedToDrink(arr) {
  // TODO: 여기에 코드를 작성합니다.
  const filteredList = arr.filter(function(el){
  return el.age >= 18;
  });

  return filteredList.map(function(el){
    return el.name;
  });
}

//filter()와 map()을 순차적으로 써야한다.
//1. 먼저, 18세 이상인 사람을 걸러내기 위해서 filter()
//2. 그 사람들의 이름을 요소로 갖는 배열리턴.즉 매핑한다 map()

 
 
 
 
 
 
 
 

arr.reduce()

 
배열의 요소를 하나로 응축할때(특히, 수의 합을 구할때 많이 쓰임)
- 학생들의 점수의 평균을 구할때
 
arr.reduce(function(acc,cur), 초기값자리)
reduce의 두번째 전달인자에 초기값이 오지 않으면, 배열의 첫번째 요소가 곧 acc(누적값)이 된다.
특히, 배열의 요소가 숫자만으로 이루어지지 않은 경우에는 초기값을 표시해주어야 한다. 예) 더해지는 값이 cur.score 일경우, 초기값 0

문제 : 객체를 요소로 갖는 배열과 문자열을 입력받아 각 요소의 'animal' 속성값이 문자열과 일치할 경우, 해당 요소의 'score' 속성값을 모두 더한 값을 리턴해야 합니다.
//입출력 예시
const records = [
  {
    score: 63,
    animal: 'dog',
  },
  {
    score: 75,
    animal: 'dog',
  },
  {
    score: 87,
    animal: 'cat',
  },
  {
    score: 98,
    animal: 'cat',
  },
  {
    score: 24,
    animal: 'dog',
  },
];

let output = calculateScore(records, 'cat');
console.log(output); // --> 185

output = calculateScore(records, 'dog');
console.log(output); // --> 162

output = calculateScore([], 'dog');
console.log(output); // --> 0

output = calculateScore(records, 'mouse');
console.log(output); // --> 0
function calculateScore(records, value) {
  // TODO: Your code here!
  const sum = records.reduce(function(acc,cur){
    if(value === cur.animal){ // 현재값의 동물과 입력한  value 가 같을경우
      return acc + cur.score;
    }else{
      return acc;
    }
  },0); // 배열이 수로만 이루어져 있지 않고, 여러 속성을 포함하고 있는 객체를 요소로 갖고 있을때 초기값 0을 설정해줌
  return sum;
}

//1. value 와 animal 의 속성값이 일치하는 경우를 if
//2. 그 요소의 score 속성값을 모두 더해서 리턴한다 reduce()

 

reduce()와 filter() 혼합버전
문제: 2차원 배열(배열을 요소로 갖는 배열)을 입력받아 모든 수(number)의 합을 리턴해야 합니다.

입출력 예시>
let output = sumOfArraysInArray([ [1, 2], [undefined, 4, '5'], [9, 'hello'], ]); console.log(output); // --> 16
function sumOfArraysInArray(arr) {
  // TODO: 여기에 코드를 작성합니다.
  const simpleArr = arr.reduce(function(acc,cur){
    return acc.concat(cur);
  });
  const onlyNumbers = simpleArr.filter(function(el){
   return typeof el === 'number';
  });
  return onlyNumbers.reduce(function(acc,cur){
  return acc + cur;
  },0);
}

/*
1. ([
  [1, 2],
  [undefined, 4, '5'],
  [9, 'hello'],
]) 
난잡하다. 풀어서 하나의 [] 안에 올수 있도록 A.concat(B)를 써서 병합해준다 (2차원배열 풀기)
2. 오직 원소들 중 number 타입인것만 거른다. (1차원배열 중에서 거르기)
2. 거른 배열에서 reduce() 를 통해 합을 구해주기
*/