_reduce
_reduce함수의 형태는 이렇습니다.
1 | _reduce(list, iter, memo){ |
첫번째인자(list) : 배열
두번째인자(iter) : 함수
세번째인자(memo) : 축적된 값
만약 list에 1~3이 존재하고 함수로 그들을 더하는 add함수가 있다고 가정하면 ,
1 | console.log( |
위의 결과가 6이 나오도록 해주는 것이 _reduce함수입니다.
어떤 함수나 list가 들어와도 reduce함수를 이용하면 재귀적수행을 쉽게 할 수 있습니다.
위의 예시의 동작순서를 설명하겠습니다.
1 | memo = add(0,1) |
add함수에 memo의 처음값 0과 배열의 시작값 1을 주고
그 결과값을 memo에 줍니다.
1 | memo = add(memo, 2) |
그 다음, 위에서 축적된 memo값이 다시 add함수의 첫번째 인자로 들어가고,
배열의 두번째 값 2가 add함수의 두번째 인자로 들어갑니다.
이제 memo값은 3이 되었습니다.
1 | memo = add(memo, 3) |
_reduce함수는 위처럼 재귀적으로 add함수가 실행된 결과를 만들어주는 역할을 합니다.
1 | function _reduce(list, iter, memo){ |
이런식으로 list의 수만큼 재귀적으로 함수를 수행하는 _reduce함수를 구현해봅시다!
앞 포스팅에서 공부했던 _each함수를 사용하면 쉽게 반복되는 작업을 처리할 수 있습니다.
1 | function _each(list, iter){ |
each 함수는 list와 iter함수를 인수로 받아서 list의 값 하나하나 함수에 반복적용하는 역할을 합니다.
1 | function _reduce(list, iter, memo){ |
결과값은 6이 나올 것입니다.
동작순서는 다음과 같습니다.
_reduce를 호출합니다.
인자로 1~3까지의 배열, 인자두개를 받아 더하는 add함수, 처음 더해지는 값 0 을 보냅니다._each함수가 실행됩니다.
인자로 1~3까지의 배열, val을 인자로 받는 함수가 보내집니다.
이 때, val값은 _each로 인해 list의 i번째 요소들이 들어갑니다._each함수 수행결과 값 6을 리턴합니다.
_reduce함수는 두번째인자로 받은 함수를 연속적으로 대신해서 호출해주고
값을 계속해서 하나의 값으로 축약해 나가는 함수입니다.이 함수는 복잡하고 반복적인 로직을 축약할때 아주 유용하게 사용될 수 있습니다.
_reduce함수는 세번째 인자(memo)를 생략하여 사용할 수도 있습니다.
위에서 만약 세번째 인자가 10이라면 16이라는 결과값을 얻게 되겠죠 .
그런데 세번쨰 인자가 없더라도 배열의 첫번째값이 memo가 되어 수행되면 더 좋겠죠.
그러기 위해서 아래처럼 _reduce에 조건을 넣어줍니다.
1 | function _reduce(list, iter, memo){ |
위에서 쓰인 slice 메소드는 slice(없애고싶은 배열개수) 형태를 띕니다.
즉, 우리는 이미 배열의 첫번째를 처음 초기값으로 지정했기 때문에
중복으로 더해지는 것을 막기위해 배열첫번째를 없애 줘야합니다.
그래서 , slice를 이용하는데요.
문제는 slice가 메소드이기 때문에 list가 무조건 Array객체일 때만 가능하다는 점입니다.
arraylike 객체에는 작동하지 않습니다.
아무튼, 이런 문제를 해결할 수 있는 방법은 다음과 같습니다.
새롭게 _rest 라는 함수를 만듭니다.
1 | function _rest(list, num){ |
_rest함수는 인자로 list와 list에서 잘라낼 갯수를 의미하는 num을 가지고,
원래 list에서 num만큼 잘라낸 list를 리턴합니다.
만약 num이 없으면 default값으로 1을 리턴합니다.
그럼이제, _rest를 사용해서 _reduce의 문제를 해결해 봅시다!
1 | function _reduce(list, iter, memo){ |
이 함수를 활용하면 재밌는 로직을 만드는 데 도움이 된다고 하네요.
_reduce함수에 대한 포스팅을 마치겠습니다!!