forEach, map, filter, reduce
- 일단 네가지 메소드의 공통점은 배열에 대한 고차원 함수이며, 기존의 배열을 건드리지 않고 반복문을 실행한다. 즉 기존의 배열에 불변성을 주면서 반복문을 실행할 수 있는 것 이다.
- 하지만 위 함수들은 모두 각기 역할과 내용이 달라서 상황에 따라서 적절히 사용하는 것이 중요한 것 같다. 그래서 어떤 차이점들이 있는지 공부해보았다.
- (가장 흔한 반복문으로는 for문이 있지만 이것은 배열에 대한 메소드는 아니고 그저 블록문 안에서 배열을 돌며 입력된 코드가 실행되는 것 뿐이다.)
.forEach() VS .map()
const arrMap = [1, 2, 3, 4, 5];
const result = arrMap.map(num => { return num +'하이'});
const arrForEach = [1, 2, 3, 4, 5];
const result2 = arrForEach.forEach(num => { return num * 3});
console.log(result)
console.log(result2)
즉 .forEach()는 리턴값이 없다
let tmpArr = []
arrForEach.forEach(num => { tmpArr.push(num + '하이')});
console.log(tmpArr)
- 즉 두 메소드 다 특정 배열을 돌면서 내부함수의 내용을 실행하는것은 맞지만 map은 모두 실행되고난 후 새로운 배열이 리턴되지만 forEach는 실행만 할뿐 새 배열을 리턴하진 않는다.
- 그렇다면 forEach는 메소드라는 점 말고는 for문과의 차이점이 없는 것 아닐까???
.filter()
- array를 돌면서 조건에 맞는 원소들만 걸러내서 새 배열에 담아 리턴해낸다.
const array1 = [1, 2, 3, 4];
const result = array1.filter((val) => val > 2)
console.log(result)
.reduce()
- reduce메소드의 내부 구성은 콜백함수와, 초기값이 들어올 수 있다.
=> array.reduce(콜백함수,초기값)
- 콜백함수의 인자는 4가지가 있다.
1.acc(누적된 현재상태)
2.cur(원본배열의 현재원소)
3.idx(원본배열의 현재인덱스) // 옵션
4.src(원본) // 옵션
=> array.reduce((acc,cur,idx,src) ⇒ (),초기값)
- 리턴되는 것은 ? array를 돌면서 콜백함수를 실행한 후 축적된 최종결과를 리턴한다.
const array1 = [1, 2, 3, 4];
const result1 = array1.reduce((accumulator, currentValue) => accumulator + currentValue,5);
console.log(result1)
const array2 = ['모모', '콩이', '보리', '블레어']
let result2 = array2.reduce((acc,cur,idx,src) => {
acc.push(`cur:${cur} idx:${idx} src[0]:${src[0]}`)
return acc
},[])
console.log(result2)
reduce는 특별하다.
reduce의 return 형태는 다양하다.
- 초기값이 어떤 형태냐에 따라서 return형태도 다르다는 것 이다.
즉 초기셋팅이 new Map()이라면 리턴값을 반복들이 축적된 Map이 리턴되는 것이다.
* 같은맥락으로 리듀스는 결과가 Object, Set, Array, Number, String....
등의 다양한 결과가 리턴될 수 있다.
reduce로 filter, map을 구현할 수 있다.
https://eloquentjavascript.net/2nd_edition/05_higher_order.html
이 글도 참고해보시면 좋을 것 같아요.
forEach는 반환값 없이 함수 연산을 계속 실행하고, forEach를 쓰는 이유는 반환 값이 필요 없는 경우에 사용하신다고 생각하시면 될 것 같아요. 그래서 자바 책에서는 종단연산이라고 해요.
제가 자바스크립트는 익숙치 않아서 ㅎㅎ.. 이렇게 보통 고차함수를 사용한다고 알고 있습니다.
map은 말 그대로 모든 요소들에 같은 연산이 필요한 경우 사용하는데, 위처럼 사용해서 forEach나 reduce같은 종다연산으로 마무리 짓는 편인 것 같습니다.(틀릴 수도 있어요. 자바는 Stream API라서 종단연산이 필수적인데, js는 그렇지는 않은 것 같아요.)
보통 저는 map filter를 많이 썼던 것 같습니다. 반복문에서 조건문이 들어가는 경우 map filter를 이용하면 간단해지는 경우가 많더라고요!
또 고차함수가 좋은 점은 별도의 저장할 배열을 따로 만들지 않아도 된다는 점도 있는 것 같아요.
글 잘 읽었습니다!!👍