기본 콘텐츠로 건너뛰기

라벨이 reduce인 게시물 표시

빈 배열로 호출하면 안되요. reduce

 예전에 some, every를 빈배열로 실행하면 어떻게 되는지 확인하였다. 추가적으로 reduce를 빈배열로 호출하면 어떻게 되는지 이야기해보고자 한다. [ 1 , 2 , 3 , 4 ]. reduce ((a, b) => a + b) reduce는 위와 같이, 반복적인 작업을 누적 시키고 싶을 때, 사용하곤 한다. const list = [] list . reduce ((a, b) => a + b) // Uncaught TypeError: Reduce of empty array with no initial value 하지만, 빈 배열로 실행을 하게 되면, 위처럼 에러가 발생 하게 된다. 물론 기본값을 설정하게 되면 에러가 발생하지 않는다. const list = [] list . reduce ((a, b) => a + b, 0 ) 왜 이렇게 구현 되어있을까? 23.1.3.24  Array.prototype.reduce (  callbackfn  [ ,  initialValue  ] )  4번 조건을 보게 되면 알 수 있다. 일단 4번 조건 까지만, 구현 해보자. Object . defineProperty ( Array . prototype , "reduceImpl" , { value : function (callback) { // 1. Let O be ? ToObject(this value). const o = Object ( this ) // 2. Let len be ? LengthOfArrayLike(O). const len = o . length || 0 // 3. If IsCallable(callbackfn) is false, throw a TypeError exception. if ( typeof callback !== 'function' ) { throw new...

reduce (함수형 프로그래밍)

  지난 주제에 reduce를 소개를 하였다.  reduce를 이용하여, map, filter, compose등 여러 함수를 만들 수 있는 것을 볼 수 있었을 것이다.  뭐 눈치는 챘겠지만 함수형 프로그래밍을 공부를 하기 위하여 작성하는 포스팅들이다. 하지만, 지난번에 작성한 reduce는 아쉬운 점이 있다. for문을 사용 하였다는 것이다.  for문이 뭐가 문제인가? 라는 생각을 할 수 있겠지만, 많은 함수형 프로그래밍 언어에서는 for, while ~ do와 같은 장치는 지원하지 않는 다는 것이다. 반복문 없이 코드를 어떻게 작성하냐 싶겠지만, 우리는 모두 안다. 재귀를 사용하면 된다는 것을....  그렇다 이번에는 reduce를 재귀를 이용하여 작성을 해보려고 한다.  reduce 재귀함수 ver. function reduce ( arr , reducer , initValue ) { if ( !arr. length ) return initValue const currentValue = arr. shift () initValue = reducer( currentValue , initValue ) return reduce ( arr , reducer , initValue ) }  재귀 함수로 코드를 작성하고자 한다면 위와 같이 작성 할 수 있을 것이다. const arr = [ 1 , 2 , 3 , 4 ] reduce(arr , (c , a) => c + a , 0 ) // 10 console.log(arr) // []  정상적으로 잘 작동 하는 듯 하였지만, shift함수를 이용 해버려서 배열의 데이터를 손상 시켰다. 이 부분은 아래와 같이 수정이 가능하다. function reduce ( arr , reducer , initValue ) { if ( !arr. length ) return initValue const [currentValue, ...othe...

reduce?

 reduce는 함수형 프로그래밍을 공부하면, 항상 보게 되는 함수이다. 처음 reduce라는 함수를 마주쳤을 때, 굳이 이런 함수를 사용해야 하나, 이런생각도 해보기도 하고, 왜 감소하다라는 뜻을 갖고 있는 reduce이지? 이런생각을 해보기도 했다.  reduce는 reducer 함수에 의한 결과를 누적 해 주는 함수이다. 누적이라는 말에서 accumulate라고 불러야 하는거 아닌가? 하고 아직도 생각 하고 있는 함수이다.  reduce의 함수 reduce ( reducer : (accumulator: Any , current: Any ) => Any , initialValue: Any ) => accumulator: Any  javascript에는 Array가 이미 reduce를 지원을 하고 있기에, 아래와 같이 사용이 가능 하다. [ 1 , 2 , 3 ]. reduce ( (accumulator , current) => accumulator + current , 0 ) // 6  구현을 해보자 한다면, 아래와 같이 간단하게 구현이 가능하다. function reduce ( arr , reducer , initValue ) { let accumulator = initValue for ( let idx = 0 ; idx < arr. length ; idx++ ) { accumulator = reducer( accumulator , arr[idx] , idx , arr ) } return accumulator }  Array.reduce와 마찬가지로 사용이 가능 하다. reduce ([ 1 , 2 , 3 ] , (accumulator , current) => accumulator + current , 0 ) // 6  reduce로 만들어보기  reduce는 기본적으로 반복을 하기 때문에 forEa...

map, filter, reduce (go, curry)

 간단하게 map, filter, reduce를 구현해보자. 1. map은 인자를 두개를 받으며, 첫번째 인자를 받아서 두번째 인자로 평가 후 배열로 리턴해준다. const map = ( iter , func ) => { const ret = [] for ( const item of iter ) { ret. push ( func( item ) ) } return ret }  위와같이 간단하게 짤 수 있다. 2. filter를 구현해보자 map과 두개의 인자를 받으며, 첫번째 인자를 받아서 두번째 인자로 평가 후 값이 있다며 배열로 리턴을 해준다. const filter = ( iter , func ) => { const ret = [] for ( const item of iter ) { if ( func( item ) ) { ret. push ( item ) } } return ret }   3. reduce는 세개의 인자를 받으며, 첫번째 인자를 받아서 두번째 인자로 받은 함수로 평가하며 축적된 값을 리턴을 한다, 이때에 세번째 인자를 초기값으로 이용한다. const reduce = ( iter , func , acc ) => { for ( const item of iter ) { acc = func(acc , item) } return acc }  이와 같이 표현 할 수 있지만, 초기값을 안넣은 경우에는 iter의 첫번째 값을 초기값으로 사용하게 변경 해보자. const reduce = ( ...args ) => { let iter = args[ 0 ] const func = args[ 1 ] let acc = args[ 2 ] if ( args. length < 3 ) { iter = iter[ Symbol . iterator ]() acc = iter. next (). value } ...