1. map()

  • 하나의 집합을 다른 형태의 집합으로 바꾼다.
  • n:n 관계
  • 모집합과 map() 이후 집합은 형태는 달라져도 개수는 동일하다.
  • map() 안에는 콜백 함수가 들어온다.
<script>
  // source 배열의 값을 두 배수한 결과 배열(twoTimes)을 만들어서 출력
  const source = [1, 4, 9, 16];

  // 방법1. for문
  {
    const twoTimes = [];
    for (let i = 0; i < source.length; i++) {
      //twoTimes.push(source[i] * 2);
      twoTimes[i] = source[i] * 2;
    }
    console.log(twoTimes);  // [2, 8, 18, 32]
  }

  // 방법 2. map() 메서드
  {
    const twoTimes = source.map(value => value * 2);
    console.log(twoTimes);  // [2, 8, 18, 32]
  }
  {
    const func = (value) => value * 2;
    const twoTimes = source.map(func);
    console.log(twoTimes);  // [2, 8, 18, 32]
  }
  {
    const func = function (value) { return value * 2; };
    const twoTimes = source.map(func);
    console.log(twoTimes);  // [2, 8, 18, 32]
  }
  {
    const twoTimes = source.map(function (value) {
      return value * 2;
    });
    console.log(twoTimes);  // [2, 8, 18, 32]
  }
  {
    function func(value) {
      return value * 2;
    }
    const twoTimes = source.map(func);
    console.log(twoTimes);  // [2, 8, 18, 32]
  }
  // 여러 맵 함수를 연결해서 사용
  {
    const twoTimes = v => v * 2;
    const tenTimes = v => v * 10;
    const plusTwo = v => v + 2;

    result = source.map(plusTwo).map(twoTimes).map(tenTimes);
    console.log(result);  // [60, 120, 220, 360]

    result = source.map(twoTimes).map(tenTimes).map(plusTwo);
    console.log(result);  // [22, 82, 182, 322]
  }
</script>

2. filter()

  • 모집합 중 일정 조건을 만족하는 것만 추출한다.
  • 결과는 전체일 수도, 없을 수도 있다.
<script>
   // 길이가 여섯 글자 이상인 단어만 추출
  const words = ['spring', 'summer', 'fall', 'winter', 'destruction', 'creation', 'rebirth'];
  
  {
    const newWords = [];
    for (let i = 0; i < words.length; i++) {
      if (words[i].length >= 6) {
        newWords.push(words[i]);
      }
    }
    console.log(newWords);
  }
  { // 가장 간단한 방법법
    const newWords = words.filter(w => w.length >= 6);
    console.log(newWords);
  }
  {
    function func(w) {
      return w.length >= 6;
    }
    const newWords = words.filter(func);
    console.log(newWords);
  }
  {
    const func = function (w) {
      return w.length >= 6;
    };
    const newWords = words.filter(func);
    console.log(newWords);
  }
  {
    const newWords = words.filter(function (w) {
      return w.length >= 6;
    });
    console.log(newWords);
  }
</script>
  • map()과 filter()를 함께 사용한 예시
<script>
  // 짝수만 추출해서 10배수한 결과를 출력
  const numbers = [1, 3, 4, 6, 11, 14];
 
  console.log(numbers.filter(n => n % 2 === 0).map(n => n * 10));

  const even = numbers.filter(n => n % 2 === 0);
  const evenTenTimes = even.map(n => n * 10);
  console.log(evenTenTimes);  // [40, 60, 140]
</script>

3. reduce()

  • 결과를 하나로 축약하여 집계한다.
  • 합계, 평균, 최댓값, 최솟값 등을 구할 때 사용한다.
<script>
  const numbers = [1, 2, 3, 4, 5];

  // 배열 요소들의 합계
  {
    let sum = 0;
    for (let i = 0; i < numbers.length; i++) {
      sum += numbers[i];
    }
    console.log(sum); // 15
  }
  {
    let sum = numbers.reduce((acc, cur) => acc + cur, 0);
    console.log(sum); // 15
  }
</script>
  // initvalue를 설정한 경우
  {
    let sum = numbers.reduce((acc, cur) => {
      const result = acc + cur;
      console.log(acc, cur, result)
      return result;
    }, 0);
    console.log(sum); // 15
  }

  // initValue를 생략한 경우
  {
    let sum = numbers.reduce((acc, cur) => {
      const result = acc + cur;
      console.log(acc, cur, result)
      return result;
    });
    console.log(sum);       // 15
  }


4. 응용

문제 1. numbers 배열의 각 항목의 값에 13을 곱한 결과 중 짝수의 합을 구하시오.

<script>html
  // numbers 배열의 각 항목의 값에 13을 곱한 결과 중 짝수의 합을 구하시오.
  const numbers = [1, 2, 3, 4, 5];

  const f1 = n => n * 13;
  const f2 = n => n % 2 === 0;
  const f3 = (a, c) => a + c;

  const result = numbers.map(f1).filter(f2).reduce(f3, 0);
  console.log(result); // 78

  const result1 = numbers.map(f1);
  const result2 = result1.filter(f2);
  const result3 = result2.reduce(f3, 0);
  console.log(result1); // [13, 26, 39, 52, 65]
  console.log(result2); // [26, 52]
  console.log(result3); // 78

  // 콜백함수를 직접 정의
  const result4 = numbers
    .map(n => n * 13)
    .filter(n => n % 2 === 0)
    .reduce((a, c) => a + c, 0);
</script>

문제 2. numbers 배열에서 짝수를 추출해서 13을 곱한 결과의 합계를 구하시오.

  const result2 = numbers.filter(f2).map(f1).reduce(f3, 0);
  console.log(result2); // 78

문제 3. 점수가 80점 이상인 학생의 이름을 출력하시오.

<script>
  const students = [
    { name: '홍길동', age: 16, score: 88 },
    { name: '홍길서', age: 18, score: 78 },
    { name: '홍길남', age: 20, score: 98 },
    { name: '홍길북', age: 22, score: 68 }
  ];

  // 점수가 80점 이상인 학생의 이름을 출력
  const f1 = student => student.score >= 80;
  const f2 = student => student.name;

  console.log(students.filter(f1).map(f2));
  students.filter(f1).map(f2).forEach(name => console.log(name));
</script>

문제 4. 점수가 80점 이상이고, 나이가 20세 이상인 학생의 이름을 출력하시오.

  const f3 = student => student.age >= 20;
  const result = students.filter(f1).filter(f3).map(f2);
  console.log(result);

문제 5. 학생별 점수 데이터 출력

<script>
  //  학생별 점수를 아래 형식에 맞춰서 콘솔에 출력

  let scores = [];
  /*  ### 학생별 점수 데이터
      0: {name: '홍길동', korean: 80, math: 90, english: 90}
      1: {name: '고길동', korean: 90, math: 80, english: 80}
      2: {name: '신길동', korean: 70, math: 80, english: 70}
 
      ### 출력 형식
      ----------- --------- --------- --------- --------- ---------
      학생이름     국어      영어      수학      합계      평균
      ----------- --------- --------- --------- --------- ---------
      홍길동       80        90        90        260       86.7
        :          :         :         :          :        :
  */

  // 배열에 학생별 점수를 추가
  scores[0] = { name: '홍길동', korean: 80, math: 90, english: 90 };
  scores.push({ name: '고길동', korean: 90, math: 80, english: 80 });
  scores.push({ name: '신길동', korean: 70, math: 80, english: 70 });
  console.log(scores);

  // 타이틀 출력
  console.log('-----------\t----\t----\t----\t----\t----');
  console.log('학생이름\t국어\t영어\t수학\t합계\t평균');
  console.log('-----------\t----\t----\t----\t----\t----');

  // 학생별 점수 출력
  scores.forEach(score => {
    const total = score.korean + score.math + score.english;
    const average = total / 3;
    console.log(`${score.name}\t\t${score.korean}\t\t${score.math}\t\t${score.english}\t\t${total}\t\t${average.toFixed(1)}`);
  });

  // 각 과목의 점수를 추출해서 합계를 계산
  const ksum = scores.map(s => s.korean).reduce((a, c) => a + c, 0);
  const esum = scores.map(s => s.english).reduce((a, c) => a + c, 0);
  const msum = scores.map(s => s.math).reduce((a, c) => a + c, 0);

  // 특정 과목의 점수를 추출해서 합계를 계산(반환)하는 함수를 정의
  const sum = subject => scores.map(s => s[subject]).reduce((a, c) => a + c, 0);

  // 풋터 출력
  console.log('-----------\t----\t----\t----\t----\t----');
  console.log(`총점\t\t${ksum}\t\t${esum}\t\t${msum}\t`);
  console.log(`총점\t\t${sum('korean')}\t\t${sum('english')}\t\t${sum('math')}\t`);
  console.log('-----------\t----\t----\t----\t----\t----');
</script>

0개의 댓글