ABOUT ME

Today
Yesterday
Total
  • Section 7. 자바스크립트 고차함수 메서드들
    자바스크립트 2023. 4. 5. 12:04

    배열의 고차함수 higher order function 메서드의 특징들은 다음과 같다

    • 다른 함수(콜백 함수)를 인자로 받는다.
    • 함수형 프로그래밍 - 변수 사용 없이 순회 작업들을 코딩한다.

     

    1. forEach - 각 요소를 인자로 콜백함수를 실행하는 메서드

    • for문의 좋은 대체제이다.
    • 단점은 예외를 던지지 않으면 종료할 수 없다. - break, continue 사용이 불가하다.

    인자들 :

    • 콜백함수 - 인자 : (현재 값, 현재 값의 인덱스, 해당 배열)
    • thisArg

    등등이 있다.

     

    const arr = [1, 2, 3, 4, 5];
    
    const result = arr.forEach(itm => {
      console.log(itm);
    });
    //1
    //2
    //3
    //4
    //5

    콜백함수를 인자로 받았고 forEach를 사용해서 출력이 된 모습이다. 그런데 result자체는 undefined를 반환한다.

    // 💡 결과로는 undefined 반환 - 실행 자체를 위한 메서드
    console.log('반환값:', result); //반환값: undefined

    여기서 forEach는 어떤 작업을 콜백으로 수행하기 위해서 존재한거지 값을 반환한 것이 아니기 때문에 그렇다.

    실제 배열을 선언하고 그것으로 작업을 수행하고 결과를 살펴보면 다음과 같다.

    const arr = [1, 2, 3, 4, 5];
    
    // 현존하는 함수를 인자로 - 💡 결과 살펴볼 것
    arr.forEach(console.log);
    //1 0 (5) [1, 2, 3, 4, 5]
    //2 1 (5) [1, 2, 3, 4, 5]
    //3 2 (5) [1, 2, 3, 4, 5]
    //4 3 (5) [1, 2, 3, 4, 5]
    //5 4 (5) [1, 2, 3, 4, 5]

    이처럼 값이 3가지가 출력이 된다. 첫 번째값은 바로 현재값이다. 두 번째는 현재 값의 인덱스이다. 마지막은 해당 배열이 되겠다.

     

    이렇게 console.log 함수를 인자로 넣어버리면 위와 같이 멋대로 3개의 값들이 출력된다. 따라서 forEach를 제대로 쓰려면 콜백함수를 무엇을 쓸 것인지 정확히 해야 한다.

    const arr = [10, 20, 30, 40, 50];
    
    // 콜백함수의 인자가 둘일 때
    arr.forEach((itm, idx) => {
      console.log(itm, idx);
    });
    //10 0
    //20 1
    //30 2
    //40 3
    //50 4

    그러면 위의 예시를 이용해서 이렇게 활용할 수 있다.

    const logWithIndex = (itm, idx) => {
      console.log(`[${idx}]: ${itm}`);
    }
    
    arr.forEach(logWithIndex);
    //[0]: 10
    //[1]: 20
    //[2]: 30
    //[3]: 40
    //[4]: 50

    2. map - 각 요소를 주어진 콜백함수로 처리한 새 배열을 반환하는 메서드

    각 요소를 받아서 어떤 기준으로 그 값을 처리한 다음 각각 기준대로 반환하는 것이다. 

     

    인자들 :

    • 콜백함수 - 인자: (현재 값, 현재 값의 인덱스, 해당 배열)
    • thisArg
    const orgArr = [1, 2, 3, 4, 5];
    
    // ⭐️ 각 콜백함수는 어떤 값을 반환해야 함
    const arr1 = orgArr.map(i => i + 1);
    const arr2 = orgArr.map(i => i * i);
    const arr3 = orgArr.map(i => i % 2 ? '홀수' : '짝수');
    
    console.log(arr1); //(5) [2, 3, 4, 5, 6]
    console.log(arr2); //(5) [1, 4, 9, 16, 25]
    console.log(arr3); //(5) ['홀수', '짝수', '홀수', '짝수', '홀수']

    여기서 각 콜백함수는 어떤 값을 반환해야 한다는 것을 명심하자. 

    그리고 원본이 수정되지 않는다. 새로운 배열을 만드는 것이기 때문이다.

     

    다른 예시를 보면

    const orgArr = [
      { name: '사과', cat: '과일', price: 3000 },
      { name: '오이', cat: '채소', price: 1500 },
      { name: '당근', cat: '채소', price: 2000 },
      { name: '살구', cat: '과일', price: 2500 },
      { name: '피망', cat: '채소', price: 2500 },
      { name: '딸기', cat: '과일', price: 5000 }
    ];
    
    
    const arr1 = orgArr.map(itm => {
      // 💡 블록 안에서는 return 문 필요함
      return {
        name: itm.name,
        cat: itm.cat
      }
    });
    
    console.log(arr1);

    블럭 안에서는 꼭 return문을 사용해야 한다. 이유는 콜백함수는 값을 반드시 반환해야 하기 때문이다.

     

    3. find, findLast, findIndex, findLastIndex - 주어진 기준으로 검색하는 메서드

    콜백함수로 인자로 넣었을 때 true를 반환하는 것들은 다음과 같다

    • find - 첫 번째 값 반환
    • findLast - 마지막 값 반환
    • findIndex - 첫 번째 값의 인덱스 반환
    • findLastIndex -  마지막 값의 반환

    공통 인자들 : 

    • 콜백함수 - 인자 : (현재 값, 현재 값의 인덱스, 해당 배열)
    • thisArg
    const arr = [1, 2, '삼', 4, 5, 6, '칠', 8, 9];
    
    const isString = i => typeof i === 'string';
    const isBoolean = i => typeof i === 'boolean';
    
    console.log(
      arr.find(isString),
      arr.findLast(isString),
      arr.findIndex(isString),
      arr.findLastIndex(isString)
    ); //삼 칠 2 6

    만약 없을 경우 값은 undefined, 인덱스는 -1을 반환한다.

    // 없을 시 값은 undefined, 인덱스는 -1 반환
    console.log(
      arr.find(isBoolean),
      arr.findLast(isBoolean),
      arr.findIndex(isBoolean),
      arr.findLastIndex(isBoolean)
    ); //undefined undefined -1 -1

     

    4. some, every - 어떤/모든 요소가 기준을 충족하는지 확인

    콜백함수에 인자로 넣은

    • some - 요소들 중 하나라도 true를 반환하는가 여부를 반환하는 메서드
    • every - 모든 요소가 true를 반환하는가 여부를 반환하는 메서드

    인자들 :

    • 콘백함수 - 인자 : (현재 값, 현재 값의 인덱스, 해당 배열)
    • thisArg
    const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    
    console.log(
      arr.some(i => i % 2),
      arr.every(i => i % 2),
      arr.some(i => i < 0),
      arr.every(i => i < 10)
    ); //true false false true

     

    5. filter - 주어진 기준을 충족하는 요소들로 새 배열을 만들어서 반환하는 메서드

    원본 배열을 수정하지 않는다.

    인자들 : 

    • 콜백함수 - 인자 : (현재 값, 현재 값의 인덱스, 해당 배열)
    • thisArg
    const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    
    const odds = arr.filter(i => i % 2);
    const evens = arr.filter(i => !(i % 2));
    const largerThan3 = arr.filter(i => i > 3);
    
    console.log(odds); //[1, 3, 5, 7, 9]
    console.log(evens); //[2, 4, 6, 8]
    console.log(largerThan3); //[4, 5, 6, 7, 8, 9]

     

    6. reduce, reduceRight

    주어진 콜백함수에 따라 값들을 접어 나가는 메서드

    인자들 :

    • 콜백함수 - 인자 : (이전값, 현재값, 현재 인덱스, 해당 배열)
    • 초기화 값

    초기화 값이 없을 때 - 첫 번째와 두 번째 값부터

    const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    
    console.log(
      arr.reduce((prev, curr, idx) => {
        console.log(`p: ${prev}, c: ${curr}, i: ${idx}`);
        return prev + curr;
      })
    );

    출력문은 다음과 같다

    이렇게 초기화 값이 없을 때는 현재값 curr에 arr의 두 번째 값인 2가 들어간 것을 알 수 있다. (prev에는 첫 번째 값인 1이 들어갔다). 현재 인덱스 값도 1임을 볼 수 있다.

    첫 번째 출력문에서 reduce를 통해 prev + curr 해서 3이 반환되었다. 

    두 번째 출력문에서 반환된 3이 prev에 들어갔고 arr에서 2 다음 값인 3이 curr에 대입된 것을 볼 수 있다. 결과는 6반환.

    세 번째 출력문에서 6이 prev에, 그리고 arr에서 3 다음 값인 4가 들어갔다.

    reduce 메서드는 이런 식으로 콜백함수를 통해 하나하나씩 접어 가는 것을 볼 수 있다.

     

    초기화 값이 있을 때의 경우는 다음과 같다

    const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    
    console.log(
      arr.reduce((prev, curr, idx) => {
        console.log(`p: ${prev}, c: ${curr}, i: ${idx}`);
        return prev + curr;
      }, 10)
    );

    초기화 값 10이 들어갔고 인덱스는 0부터 시작한다는 것을 알고 넘어가자.

     

    reduceRight는 시작 방향이 오른쪽인 메서드이다.

    const arr = ['가', '나', '다', '라', '마', '바', '사'];
    
    console.log(
      arr.reduceRight((prev, curr, idx) => {
        console.log(`p: ${prev}, c: ${curr}, i: ${idx}`);
        return prev + curr;
      })
    );

    출력문을 확인해보면 알 수 있다.

     

    7. sort - 배열을 (주어진 기준대로) 정렬하는 메서드

    • 배열 자체의 순서를 바꾼다 - 원본 수정
    • 해당 배열을 반환한다

    인자들 : 

    콜백함수 (필수는 아니다) - 인자 : (앞의 값, 뒤의 값)

     

    1. 인자가 없을 경우는 다음과 같다

    const arr = ['라', '사', '다', '가', '바', '마', '나'];
    
    arr.sort();
    
    console.log(arr); //['가', '나', '다', '라', '마', '바', '사']

    인자가 없을 경우 기본적으로 오름차순으로 정렬이 되는 것을 볼 수 있다.

     

    let randomWord = 'DBKGICAHFEJ';
    
    console.log(
      randomWord
      .split('')
      .sort()
      .join('')
    ); //ABCDEFGHIJK
    
    console.log(randomWord); //DBKGICAHFEJ

    이번에는 sort를 썼는데도 원본은 바뀌지 않았다.

    이유는 split을 사용하면 randomWord가 별도의 배열로 반환되기 때문이다. 그리고 그 배열에다 sort를 했으니 원본은 바뀐것이 없게 되는 것이다. 

     

    만약 숫자를 sort하는 경우는 다음과 같다

    const arr = [1, 2, 30, 400, 10, 100, 1000];
    console.log(arr.sort()); //[1, 10, 100, 1000, 2, 30, 400]

    숫자일 경우 오름차순으로 정렬이 되지 않는 것을 볼 수 있다. 

    이유는 숫자일 경우 문자열로 암묵적 변환하여 오름차순으로 정렬하기 때문이다. 

     

    정확한 정렬을 위해 - 콜백 함수를 사용

    • 두 인자 a와 b: 인접한 두 요소
    • 0보다 큰 값 반환 : b를 앞으로 - 순서 뒤집는다
    • 0 반환 : 순서 유지 - ECMAScript 표준은 아니므로 환경마다 다를 수 있다
    • 0보다 작은 값 반환 : a를 앞으로 - 사실상 순서 유지다

    8. flatMap - map 한 다음 flat 매핑해서 펼치는 메서드

    인자들 :

    • 콜백함수 - 인자: (현재 값, 현재 값의 인덱스, 해당 배열)
    • thisArg
    const arr = [1, 2, 3, 4, 5];
    
    console.log(
      arr.map(i => [i, i, i])
    );

    그냥 map 매서드를 사용했을 때의 출력문은 다음과 같다

    이것을 flat한 것을 flatMap이라고 하는 것이다.

    console.log(
      arr.flatMap(i => [i, i, i])
    ); //(15) [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5]

    먼저 map한 결과에 flat이 적용된 것을 볼 수 있다.

Designed by Tistory.