타입스크립트 기초 - 9

Stulta Amiko·2022년 7월 1일
0

타입스크립트 기초

목록 보기
9/24
post-thumbnail

선언형 이용하기

const range = (from: number,to: number): number[] => from<to ? [from,...range(from+1,to)] : []
const fold = <T>(array:T[],callback: (result: T,val: T)=>T, initValue: T) =>{
    let result: T = initValue
    for(let i=0;i<array.length;++i){
        const value = array[i]
        result = callback(result,value)
    }
    return result
}
let num : number[] = range(1,101)
let result = fold(num,(result,value)=>result+value,0)

console.log(result)

보통 사용하는 for문을 이용하는것이 아닌
선언형으로 1부터 100까지의 합을 구하는 코드이다.
재귀를 사용하기 때문에 효율이 더 좋다.
코드 자체가 좀 난해해서 이해가 잘안된다.
하지만 계속 보다보면 어떻게 작동하는지 알 수 있다.

const range = (from: number,to: number): number[] => from<to ? [from,...range(from+1,to)] : []

const fold = <T>(array:T[],callback: (result: T,val: T)=>T, initValue: T) =>{
    let result: T = initValue
    for(let i=0;i<array.length;++i){
        const value = array[i]
        result = callback(result,value)
    }
    return result
}

const filter = <T>(array: T[],callback: (value:T,index?:number)=> boolean): T[] =>{
    let result: T[] = []
    for(let index: number = 0;index<array.length;++index){
        const value = array[index]
        if(callback(value,index))
            result = [...result,value]
    }
    return result
}
let num : number[] = range(1,101)
let result = fold(num,(result,value)=>result+value,0)
const is_odd = (n: number): boolean => n%2 != 0
let result2 = fold(filter(num,is_odd),(result2,value)=> result2+value,0)
console.log(result2)

위 코드는 홀수의 합만 따로 분류해서 더하는 코드이다.
물론 반복문을 사용하면 편리하게 구할 수 있지만 책에서는 이제 함수형 프로그래밍을 익숙하게 하기 위해서인지
재활용이 가능한 구문을 만들어 놨다.
이게 좀 골때린다. 초보라서 이해하는데 좀 걸렸다.
이것때문에 오랜시간 고민을 하면서 이해를 했다.
사실 두고보면 별거 아니긴 하지만 아직 몇몇개념이 익숙하지 않아서 그런것 같다.

const range = (from: number,to: number): number[] => from<to ? [from,...range(from+1,to)] : []

const fold = <T>(array:T[],callback: (result: T,val: T)=>T, initValue: T) =>{
    let result: T = initValue
    for(let i=0;i<array.length;++i){
        const value = array[i]
        result = callback(result,value)
    }
    return result
}

const filter = <T>(array: T[],callback: (value:T,index?:number)=> boolean): T[] =>{
    let result: T[] = []
    for(let index: number = 0;index<array.length;++index){
        const value = array[index]
        if(callback(value,index))
            result = [...result,value]
    }
    return result
}

const map = <T,Q>(array: T[],callback: (value: T,index?:number)=>Q):Q[]=>{
    let result: Q[] = []
    for(let index: number = 0;index<array.length;++index){
        const value = array[index]
        result = [...result,callback(value,index)]
    }
    return result
}
let num : number[] = range(1,101)
let result = fold(num,(result,value)=>result+value,0)
const is_odd = (n: number): boolean => n%2 != 0
let result2 = fold(filter(num,is_odd),(result2,value)=> result2+value,0)
let result3 = fold(map(num,value=>value*value),(result,value)=>result+value ,0)
console.log(result2)
console.log(result3)

map까지 구현한 모습이다.
사실 타입스크립트 내에서 전부 제공하고 있는 기능이여서 이렇게 구현해서 쓸일은 없겠지만 혹시 모르니깐 이렇게 구현해본다.
그리고 이해가 안되기때문에 이해하는데 또 시간이 오래걸린다.

함수형 프로그래밍을 이용하는것이 기존에 어느정도 프로그래밍에 익숙한 사람들에겐
익숙하거나 이해를 하는데 쉽고 효율적인 방법이라고 생각될듯 싶다.
초보인 나에게는 이해하는데는 확실히 시간이 걸리는것 같고
만약 입문을 하는 사람들에게는 함수형 프로그래밍 자체가 훨씬 더 난해하게 느껴질것 같다.

배열의 메서드

filter

filter 메서드의 경우 다음과 같은 구조를 가지고 있다.

filter(callback: (value: T,index?: number): boolean): T[]

위와같은 형태를 가지고있다.

let num : number[] = range(1,11)

let odds: number[] = num.filter((value)=>value%2!=0)
let evens: number[] = num.filter((value)=>value%2==0)

console.log(odds,evens)

실행결과
[ 1, 3, 5, 7, 9 ][ 2, 4, 6, 8, 10 ]

filter 함수의 경우 위와같은 방식으로 첫번째 파라미터로
배열이 있을때 메서드로 사용하고 파라미터로는 함수를 넣는 모습을 볼 수 있다.

그렇게 짝수배열과 홀수배열을 얻을 수 있다.

map

map 메서드는 다음과 같은 구조를 가지고있다.

map(callback:(value: T,index?: number):Q):Q[]

map 매서드는 배열을 순회하면서 함수를 실행시켜서 저장한 배열을 반환한다.

let num : number[] = range(1,11)

let arr: number[] = num.map((val: number)=> val*val)

console.log(arr)

실행결과
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

위와같은 방식으로 map 메서드를 사용할 수 있다.

reduce

앞에서 구현한 fold는 reduce로 대체할 수 있다.

reduce(callback: (result: T,value T), initialValue: T): T

reduce는 위와같은 형태로 구성이 되어있다.

let num : number[] = range(1,101)
let add : number = num.reduce((result: number,value: number)=> result+value,0)

console.log(add)

reduce 메서드를 이용하여 1부터 100까지의 합을 구하는 모습이다.
배열의 인덱스를 처음부터 순회하면서 넘어갈떄마다 기존의 값과 그 인덱스의 값을 합치는 모습을 볼 수 있다.

만약 곱셈을 하려면 initialvalue에 1이 있어야한다.

순수함수

부수효과가 없는 함수를 순수 함수라고 한다.

  • 함수 몸통에 입출력 관련 코드가 없어야한다.
  • 매개변수 값을 변경하지 않는다.
  • 몸통에서 만들어진 결과를 반환한다.
  • 함수 내부에 전역변수나 정적변수가 없다.
  • 예외를 발생시키지 않는다.

등등이 있다.

예를들어 단순히 더한후에 반납하는 함수는 위 조건을 만족하는 순수함수 이다.

0개의 댓글