이 문제를 어떻게 해결하면 좋을까? 일단 경우의 수를 모두 구해야하니 for문을 써야한다는 것은 알겠다. 하지만 내가 아는 for문은 for(i=0, i<array.length, i++) 정도의 수준이라 이에 적합한 식을 만들기 어려웠다. 그래서 구글링을 하다가 'forEach'라는 개념을 새로 알게 되었다!
forEach는 주로 배열의 객체에서 사용하는 메서드다. 배열의 요소들을 반복해서 작업을 수행할 수 있다. 배열의 각 요소에 대해 callback을 실행하는데, 배열을 순회하므로 중간에 "break;" 문을 사용할 수 없다. 이 점이 for()문과의 차이점이다. (for문은 break가 없으면 무한으로 돌아갈 위험이 있음)
Array.forEach()
이런 식으로 사용하면 된다.
map과의 큰 차이는 forEach 함수 자체가 return 하는 것은 아무것도 없다는 것이다. forEach 함수를 탈출하고 싶을 때 그냥 return을 사용하면 된다. map은 요소가 수정된 새로운 배열이 return되었다면, forEach는 아무것도 return하는 것이 없다. 그래서 forEach로 전달되는 callback 함수에서도 return하는 것이 없다. forEach는 단지 for문 대신 사용하는 반복 메서드인 셈이다.
예시 1:
let startWithNames = [];
let names = ['a', 'ab', 'cbb', 'ada'];
names.forEach(el => {
if (el.startsWith('a')) {
startWithNames.push(el);
}
});
예시 2:
let hasC = false;
let arr = ['a', 'b', 'c', 'd'];
arr.forEach(el => {
if (el === 'c') {
hasC = true;
return;
}
});
만약 forEach에서 현재 index를 알고 싶으면 두 번째 인자로 받을 수 있다.
예시 :
let idxOfC = -1;
let arr = ['a', 'b', 'c', 'd'];
arr.forEach((el, idx) => {
if (el === 'c') {
idxOfC = idx;
return;
}
});
위에서 자꾸 map과 비교했는데 그럼 map은 뭘까?
map( )은 배열을 순회하면서 배열의 각 원소들을 출력한다. 특이한 점은 forEach( )와 달리 실행결과를 모은 새 배열을 리턴한다는 것이다. map의 용도를 제대로 살리려면 return 문이 있어야 한다. return이 포함되면 배열의 각 요소에 대해 callback을 실행하고 실행결과를 모은 새 배열을 리턴하기 때문이다.
예시:
const arr = [1, 2, 3];
const squares = arr.map(x => x * x);
forEach와 map이 뭔지는 대충 알고나면 이런 질문이 떠오른다.
그래서 얘네를 어디다 쓰는데?!
단순 반복이라면 for( ), 배열을 순회하려면 forEach( ), 배열을 순회 후 새 배열을 얻고 싶다면 map( ) 사용할 것이 권장된다.
그렇다... 셋 다 나름의 용도가 있었다.