-
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이 적용된 것을 볼 수 있다.
'자바스크립트' 카테고리의 다른 글
Section 8. 자바스크립트 Object 깊게 다루기 (0) 2023.04.05 Section 7. 자바스크립트 배열의 스프레드와 디스트럭쳐링 (0) 2023.04.05 Section 7. 자바스크립트 배열의 기본 메서드들 (0) 2023.04.04 Section 7. 자바스크립트 배열의 특징과 생성 (0) 2023.04.04 Section 6. 자바스크립트 Date 객체 (0) 2023.03.31