타입스크립트 기초 - 15

Stulta Amiko·2022년 7월 25일
0

타입스크립트 기초

목록 보기
15/24
post-thumbnail

서술자와 조건 연산

함수형 프로그래밍에서 boolean 타입 값을 반환해 어떤 조건을 만족하는지를 판단하는 함수를 서술자라고 한다.

람다 라이브러리 내부에는 수를 비교해 boolean 타입으로 반환하는 서술자들을 제공한다.

import * as R from 'ramda'

R.lt(a)(b): boolean // a < b 이면 true
R.lte(a)(b): boolean // a <= b 이면 true
R.gt(a)(b): boolean // a > b 이면 true
R.gte(a)(b): boolean // a >= b 이면 true

수의 크기를 판단하는 서술자는 위와 같은 형식으로 제공한다.
filter 함수와 결합해서 사용하는 예제코드를 보면 다음과 같다.

import * as R from 'ramda'

R.pipe(
    R.filter(R.lte(3)),
    R.tap(n => console.log(n))
)(R.range(1,11))

위 코드를 읽어보면 알겠지만
결과는 3부터 10까지 출력하게 된다.
필터에서 true인 결과만 저장하게 되니깐 3보다 작을땐 전부 false를 출력하게 될것이고 이에따라 3이상의 수만 저장되게 된다.

import * as R from 'ramda'

R.pipe(
    R.filter(R.lte(3)),
    R.filter(R.gt(7)),
    R.tap(n => console.log(n))
)(R.range(1,11))

위 코드는 3 <= x < 7을 구현한 코드이다.
위 코드를 출력하게되면 3보다 크고 7보다 작은 수가 출력되게 될것이다.


allPass/anyPass

allPass(서술자) // 배열의 조건을 모두 만족하면 true
anyPass(서술자) // 배열의 조건을 하나라도 만족하면 true

import * as R from 'ramda'

type NumberToBooleanFunc = (n: number) => boolean
const selectRange = (min: number,max: number): NumberToBooleanFunc =>
    R.allPass(
        [R.lte(min),
        R.gt(max)]
    )

R.pipe(
    R.filter(selectRange(3,9)),
    R.tap(n => console.log(n))
)(R.range(1,11))

위 코드는 allPass를 응용해서 3 <= x < 9를 구현한 모습이다.


not / ifElse

not 함수는 true이면 false를 반환하고 false이면 true를 반환하는 함수이다.
!연산자와 유사한 느낌인거같다.
위에서 구현한 selectRange 함수와 반대되는 함수를 쉽게 구현할 수 있다.

import * as R from 'ramda'

type NumberToBooleanFunc = (n: number) => boolean
const selectRange = (min: number,max: number): NumberToBooleanFunc =>
    R.allPass(
        [R.lte(min),
        R.gt(max)]
    )

const notRange = (min: number,max: number) => R.pipe(selectRange(min,max),R.not)
R.pipe(
    R.filter(notRange(3,9)),
    R.tap(n => console.log(n))
)(R.range(1,11))

기존의 selectRange를 이용하면서 이런식으로 구현이 가능하다.
위 함수는 1부터 10까지 기존의 selectRange(3,9)에 해당되었던 값의 정반대인 값을 출력한다.
기존이 다음과 같은 식을 구현했다면 3 <= x < 9
위에서 구현한 코드는 x < 3 and x >= 9
range 배열 내에서 저 조건문에 맞는 수를 남기게 된다.

ifElse는 세가지 매개변수를 포함한다.

R.ifElse(
조건서술자,
true일때 실행하는 함수,
false일때 실행하는 함수
)

위와 같은 형식으로 구성된다.

import * as R from 'ramda'

const input: number[] = R.range(1,11), halfValue = input[input.length/2]

const suborAdd = R.pipe(
    R.map(R.ifElse(
        R.lte(halfValue),
        R.inc,
        R.dec
    )),
    R.tap(n => console.log(n))
)

const result = suborAdd(input)

ifElse를 응용하는 코드로 하프밸류보다 작으면 1씩 빼고
하프밸류보다 크면 1씩 추가하는 코드를 가져왔다.
첫번째 파라미터의 값에 부합하는 애들은 1씩 빼주고 값에 부합하지 않는애들은 1씩 더해주는 코드이다.
이처럼 간결하게 작업을 수행할 수 있는 함수들이 람다라이브러리에 존재한다.

문자열 다루기

trim
trim은 문자열 앞뒤의 공백을 제거해준다.

import * as R from 'ramda'

console.log(
    R.trim('\t hello \t')
)

toLower / toUpper

이름만봐도 알 수 있듯이 대문자로 혹은 소문자로 바꿔주는 함수이다.

import * as R from 'ramda'

console.log(
    R.toUpper('hello'),
    R.toLower('HELLO')
)

구분자를 사용해 문자열을 배열로 변환

R.split 함수는 구분자를 사용해서 문자열을 배열로 바꿔준다.
R.join함수는 문자열 배열을 문자열로 바꿔준다.

import * as R from 'ramda'

const words: string[] = R.split(' ')(`Hello World!, I'm Peter`)
console.log(words)

위 코드를 출력하면 문자열을 배열로 만들어준다. 구분자는 ' ' 이다.

실행결과
[ 'Hello', 'World!,', "I'm", 'Peter' ]


toCamelCase 함수 만들기

import * as R from 'ramda'

type StringToStringFunc = (string) => string

const toCamelCase = (delim: string): StringToStringFunc =>{
    const makeFirstToCapital = (word: string) =>{
        const characters = word.split('')
        return characters.map((c,index) => index == 0 ? c.toUpperCase() : c).join('')
    }

    const indexedMap = R.addIndex(R.map)
    return R.pipe(
        R.trim,
        R.split(delim),
        R.map(R.toLower),
        indexedMap((value: string,index: number) => index > 0 ? makeFirstToCapital(value):value
        ),
        //@ts-ignore
        R.join('')
    ) as StringToStringFunc
}

console.log(
    toCamelCase(' ')('Hello World'),
    toCamelCase('_')('Hello_Albert')
)

위와같은 방식으로 만든다. CamelCase가 뭔가하면 이제 이름을 지을때 규칙같은것이다.
첫문자는 소문자로 그리고 띄워쓰기를 할 공간에 대문자 문자를 넣는것이다.
위 코드는 다음에 한번 더 해석해보는걸로 해야겠다.

0개의 댓글