filter는 콜백함수를 인자로 받아 배열을 리턴한다.
import { range } from "../day01/range";
const array1: number[] = range(1, 10 + 1);
// value가 2로 나눈 나머지가 0이 아닌것. 즉, 홀수임
let odd = array1.filter((value) => value % 2 != 0)
// value가 2로 나눈 나머지가 0인것. 즉, 짝수임
let even = array1.filter((value) => value % 2 == 0)
console.log(odd)
console.log(even)
filter는 index라는 두번째 매개변수도 제공한다. index?:
const array1: number[] = range(1, 10 + 1);
const half = array1.length / 2
//해당 배열의 index도 제공한다.
const belowHalf:number[] = array1.filter((v,i) => i < half)
const overHalf:number[] = array1.filter((v,i) => i >= half)
console.log(belowHalf, overHalf)
//[ 1, 2, 3, 4, 5 ] [ 6, 7, 8, 9, 10 ]
filter와 달리 map 메서드는 입력과 달리 새로운 타입의 배열을 만들 수 있다.
import { range } from './../day01/range';
const names: string[] = range(1, 5 + 1).map((v, i) => `[${i}] : ${v}`)
console.log(names)
다음 코드는 range함수로 생성한 number타입의 배열을 map을 이용해서 string 타입으로 바꾼 코드 이다.
앞서 구현했던 fold함수 대신 reduce를 이용할 수 있다.
import { range } from './../day01/range';
//1 부터 100까지 배열을 만들고 reduce를 이용해서 더해가면서 값을 접어나간다. 이때 초기 값으로 0을 세팅한다.
const reduceSum:number = range(1, 100 + 1).reduce((result : number, value:number) => result + value, 0)
console.log(reduceSum) //5050
주의
만약 reduce 함수의 초기값을 0으로 세팅한다면 값 중에서 곱하기가 없는지 확인을 해야한다. 곱하기가 있다면 초깃 값을 0이 아닌 1로 세팅한다.
함수형 프로그래밍에서 함수는 순수 함수(pure function)라는 조건을 만족해야 한다. 그러나 타입스크립트의 Array 클래스에는 순수 함수 조건에 부합하지 않는 메서드가 많다. 따라서 타입스크립트로 함수형 프로그래밍을 하면서 배열의 메서드를 사용 할 때는 해당 메서드가 어떤 특징을 가지는지 살펴야 한다.
순수 함수는 부수효과(side-effect)가 없는 함수를 말한다.
부수효과는 함수가 가진 목적 외에 다른 효과가 나타나는 것을 의미하고 대부분 부작용이다. 반면 부수 효과가 있는 함수는 불순 함수(impure function)이라고 한다.
함수형 프로그래밍에서 발생하는 부수 효과는 함수를 순수 함수 형태로 작성을 해야 제거 할 수 있다.
타입스크립트는 순수 함수를 쉽게 구현하도록 readonly 키워드를 제공한다. readonly타입으로 선언된 매개변수값을 변경하는 시도가 있다면 문제를 알려준다.
변수가 const나 readonly를 명시하고 있으면 변수값은 초깃값을 항상 유지한다. 이러한 변수는 변경할 수 없다는 의미로 불변 변수라고 한다.
const나 readonly를 명시하지 않는 변수는 언제든 값을 변경할 수 있고 이렇게 변수를 변경할 수 있다는 의미는 가변 변수라고 한다.
프로그래밍 언어에서 어떤 변수값을 다른 변수값으로 설정하는 것을 복사라고 한다. 복사에는 깊은 복사와 얕은 복사가 있다.
순수 함수를 구현할 때는 매개변수가 불변성을 유지해야 하므로, 매개변수를 가공하려고 할때 깊은 복사를 실행해 매개변수값이 변경되지 않게 해야 한다.
깊은 복사의 예
let original = 1
let copied = original
copied += 2
console.log( original, copied) // 1 3
original의 변수값은 변하지 않았는데 이것이 깊은 복사이다.
타입스크립트에서 number와 boolean 타입은 깊은 복사 형태로 동작한다.
객체와 배열은 얕은 복사 방식으로 동작하는데 다음 코드를 살펴보자
const originalArray = [5,3,9,7]
const shallowCopiedArray = originalArray
shallowCopiedArray[0] = 0
console.log(originalArray) //[0,3,9,7]
이렇듯 배열과 객체는 주소값을 참조하는 방식으로 같은 주속값을 가지기 때문에 원본의 데이터도 바뀌게 된다.
전개 연산자를 사용해 배열을 복사하면 깊은 복사를 할 수 있다.
새로운 주소값을 할당하는 것
const oArray = [1,2,3,4]
const deepCopiedArray = [...oArray]
deepCopiedArray[0] = 0
console.log(deepCopiedArray, oArray) // [0,2,3,4] [1,2,3,4]
위와 같이 원본의 데이터가 바뀌지 않았다!
배열이 제공하는 filter와 map에서는 깊은 복사 형태로 동작한다. filter메서드를 사용하면 원본 배열의 내용을 훼손하지 않으면서 조건에 맞지 않는 아이템을 삭제 할 수 있다.
이를 활용해서 새로운 배열을 리턴하는 filter에 원하는 조건이 아닌 것을 리턴하는 함수를 만들어 보자
//filter 메서드를 이용하여 새로운 함수를 정의
const pureDelet =<T>(array : readonly T[], cb:(val:T, index?:number)=>boolean) => array.filter((val, index) => cb(val, index) == false)
const mixedArray: object[] = [[], { name: 'lee' }, { name: 'lee', age: 2 }, ['dddddd']]
//새로운 함수를 사용하여 객체만 잘라내는 결과를 얻음
const objectOnly = pureDelet(mixedArray, (val) => Array.isArray(val))
console.log(objectOnly)
자바스크립트에는 튜플타입은 존재하지 않는다. 단순히 배열의 한 종류로 취급이 된다.
배열에 들어가는 값들의 모든 값이 다르면 튜플이라고 하는데 배열의 타입을 any로 정의하면 타입기능이 무력화 됨으로 다음과 같이 정의할 수 있다.
const array2:[boolean, string] = [true, 'HellowTuple']
보통 튜플을 사용할때는 별칭을 이용하여 의미를 명확하게 한다.
위와 같은 코드보다는 별칭을 만들어 사용하게 된다.
export type ResultType = [boolean, string]