새소식

Study/JavaScript

[JS] forEach 란, map 이란, filter 란, reduce 란? / 고차함수 / 구조, 동작 방식, 설명

  • -

forEach, map, filter, reduce

모두 고차함수 (함수를 인자로 받을 수 있는 함수)

 
1. forEach
forEach() 메서드는 주어진 함수를 배열 요소 각각에 대해 실행합니다
이게 무슨 말이냐면... 

a = [10, 11, 12, 13, 14, 15, 16]

// forEach란? for 대신 사용, 아마 이렇게 돌아갈 듯!
function forEach(predicate, thisArg) {
for (let i = 0; i < a.length; i++) {
predicate(a[i], i)
}
}

let forEach_result = a.forEach((v, i) => { // 인자로 넘어가는 매개변수로 넘어가는 함수가 콜백함수
console.log(v, i, this) // 여기는 forEach의 내부가 아니라 콜백함수의 내부
}, [1, 2]);

console.log(forEach_result)

function forEach는 이렇게 되어있어서 forEach 메소드를 사용할 수 있는 거 아닐까 하고 짐작하며 정리한 내용입니다!

console.log에 있는 this에는 [1, 2]가 찍힙니다.

 

 

2. map

map() 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환합니다.
요소 각각을 돌며 새.로.운 배열을 반환

a = [10, 11, 12, 13, 14, 15, 16]

// map이란? 아마 이렇지 않을까.. 새로운 배열을 리턴하지만 길이는 원본과 같다!
function map(predicate, thisArg) {
let list = []
for (let i = 0; i < a.length; i++) {
list.push(predicate(a[i], i))
}
return list
}

let map_result = a.map((v, i) => {
return v * v
// [100, 121, 144, 169, 196, 225, 256]
})

// 만약 짝수를 리턴하고 싶다면
let map_result2 = a.map((v, i) => {
if (v % 2 === 0) return v
// 어떻게 리턴될까요? 짝수만 리턴될까요?
// map은 무조건 원본 배열과 같은 길이를 리턴합니다.
// [10, undefined, 12, undefined, 14, undefined, 16]
})

console.log(map_result)
console.log(map_result2)
 
중요한 것은 맵은 새로운 배열을 반환하지만 원본 배열과 길이가 같은 새로운 배열을 반환합니다.
위에 적은 예시처럼 a에서 짝수만 반환하게 식을 짜놓으면
a = [10, 11, 12, 13, 14, 15, 16] // 원본 배열
우리는 [10,12,14, 16] 이렇게 반환하길 원하지만 
실제로는 원본 길이가 같아야 하기 때문에
[10, undefined, 12, undefined, 14, undefined, 16]
이렇게 반환해줍니다. 
 

 

3. filter

filter() 메서드는 주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환합니다.

위에서 짝수만 리턴하고 싶을 때 바로 filter를 쓰면 되겠죠

a = [10, 11, 12, 13, 14, 15, 16]
// filter란? 원하는 요소만 남기고 리턴해주는 메소드 / 길이가 다를 수 있다! / 원리는 아마도..
function filter(predicate, thisArg) {
let list = []
for (let i = 0; i < a.length; i++) {
if (predicate(a[i], i)) list.push(a[i])
}
return list
}

let filter_result = a.filter((v, i) => {
return v % 2 === 1
})

console.log(filter_result)

filter는 이해하기 굉장히 쉽습니다.

말그대로 필터해주는 겁니다! 조건에 맞는 값만 통과시켜 통과한 애들로 새로운 배열을 반환합니다.

 

 

4. reduce

reduce() 메서드는 배열의 각 요소에 대해 주어진 리듀서(reducer) 함수를 실행하고, 하나의 결과값을 반환합니다.

이렇게 설명만 되어 있으면 헷갈립니다.. 코드와 함께 보시죠

a = [10, 11, 12, 13, 14, 15, 16]
// reduce란? 첫번째 인자는 콜백함수, 두번째는 초기화값
function reduce(predicate, val) {
let reduce_res = val

for (let i = 0; i < a.length; i++) {
reduce_res = predicate(reduce_res, a[i])
// predicate가 호출하면 아래의 return acc + v가 실행되고 reduce_res가 acc + v 값이 됨!
// 그게 또 predicate의 인자로 들어가고 또 호출해서 누적된 acc 에 v가 또 더해지고 반복
}

return reduce_res
}
// reduce_res가 acc에 들어가고 a[i]가 v로 넘어감

let reduce_result = a.reduce((acc, v) => { // 콜백함수의 첫번째 인자는 누적, 두번째가 value
return acc + v // 이렇게하면 a의 모든 값을 다 더한 값이 리턴
// return acc+v가 다시 acc로 들어간다! 그게 또 acc+v가 되고 그 값이 또 acc로 넘어가고 반복
})

console.log(reduce_result)

a = [1, 2, 3, 4, 5] 일때

a.reduce((acc, v) => {

  return acc + v

}) 를 하면 15가 나옵니다

acc는 누적값이 들어가고 v에는 그 누적값에 더해줄 value가 들어갑니다. (위의 상황에선)

초기 값 지정이 없으니 처음엔 acc에 1이 v에 2가 들어가겠죠

1 + 2 = 3 여기서 이 3이 acc에 또 들어가고 v에는 2 다음 값인 3이 들어갑니다.

그럼 3+3=6 6이 acc에 들어가고 v에는 4가 들어가고 

다음은? 6+4=10 10이 들어가고 v에는 5 이렇게 해서 최종으로 15가 나오는 겁니다.

 

 

끄으ㅡㅇㅌ

Contents

포스팅 주소를 복사했습니다.

이 글이 도움이 되었다면 공감 부탁드립니다.