> For the complete documentation index, see [llms.txt](https://taewoongs-organization.gitbook.io/jtwjs-dev-wiki/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://taewoongs-organization.gitbook.io/jtwjs-dev-wiki/dev_note/fp/undefined-12.md).

# 함수형 도구

{% hint style="info" %}
기계에게 어떤 일을 시켜야 하는지의 관점에서 벗어나 사람이 사고하는 방식으로 코드를 작성하는 것이 핵심
{% endhint %}

## 함수형 도구 (map, filter, reduce, ...etc+)

> **순수함수와 고차함수를 사용해서 효과와 계산을 분리**하여 **함수들을 서로 합성하고 조합**해서 사용하는 것은 결국 **사람의 생각과 최대한 가까운 코드를 작성하기 위함**이다.

* 반복문을 대채해서 코드의 목적을 더 명확하게 할 수 있다

{% hint style="info" %}
아무리 map, filter, reduce 함수를 많이 쓰더라도 이 목적을 달성하지 못한다면 함수형 프로그래밍의 장점을 제데로 누리지 못하는 것 😂
{% endhint %}

### Array 여러개 일 수 있는 값

> 데이터 요소의 집합을 나타내는 자료구조

* `Array`를 반환하는 함수는 단 하나의 값이 반환되는 것이 아닌 0개 또는 여러개의 값이 반환이 될 수 있기 때문에 값이 하나로 결정되지 않는다 하여 **비결정적**이라 부른다.
* 반복문 대신 `map`, `filter`, `reduce` 등을 사용하면 배열의 요소에 직접 접근하지 않고도 동일한 처리를 수행할 수 있다.

### map()

* 보조 함수를 통해 `iterable` 안의 값에 1:1로 매핑되는 어떠한 값을 수집할 때 사용
* 배열의 모든 요소에 함수를 적용해 새로운 배열을 반환한다. 각 요소는 전달한 콜백 함수에 의해 변환된다.
* 입력값 배열의 원소의 갯수와 동일한 길이의 배열을 반환해야한다.&#x20;

{% hint style="info" %}
**Iterable**은 반복 가능한 객체로 각 요소들을 하나씩 차례대로 반환할 수 있는 객체를 의미한다.
{% endhint %}

```typescript
const map = <A, B>(iter: Array<A>, f: (x: A) => B): Array<B> => {
  const res: Array<B> = [];
  for (const a of iter) {
    res.push(f(a));
  }
  return res;
} 
```

* `map()` 함수 내부에 `for loop` 를 사용하긴 했지만 사용하는 입장에서 보면 어떻게 구현되어있는지 신경쓸 필요가 없고 단지 주어진 배열의 모든 원소에 주어진 함수를 적용시켜 새로운 배열을 얻는다는 것만 알면 된다.
* 즉, 기존의 직접 다루던 부수효과를 분리해서 격리한 후에 별도의 효과로 취급할 수 있도록 추상화한 것

{% hint style="info" %}
`map()`에 넘기는 함수가 계산일 때 가장 사용하기 쉽다.

`map()`에 계산을 넘기면 `map()`을 사용하는 코드도 계산이 되고 액션을 넘기면 요소의 갯수만큼 액션을 호출하게 되고 `map()`을 사용하는 코드 역시 액션이 된다.
{% endhint %}

### filter()

* 보조 함수를 통해 `iterable` 안의 조건에 충족하는 어떠한 값을 수집할 때 사용
* 어떤 배열의 하위 집합을 선택해 새로운 배열을 반환핞다.
* **`술어(predicate)`**&#xB97C; 전달하여 특정 요소들을 필터링한다.

```typescript
const filter = <T>(iter: Array<T>, f: (x: A) => boolean): Array<T> => {
  const res: Array<T> = [];
  for (const a of iter) {
    if(f(a)) res.psuh(a);
  }
  return res;
} 
```

{% hint style="info" %}
술어란 `false` 또는 `true` 를 반환하는 함수
{% endhint %}

### reduce()

* 배열의 요소들을 순회하여 하나의 값으로 누적할 때 사용
* 초깃값을 가지고 어떤 배열의 요소를 조합해 하나의 값을 만든다.

```typescript
const reduce = <A, B>(iter: Array<A>, acc: B, f: (x: B, y: A) => B): B => {
  let res: B = acc;
  for (const a of iter) {
    res = f(res, a);
  }
  return res;
} 
```

{% hint style="info" %}
**초기값을 결정하는 방법**&#x20;

*1. 계산이 어떤 값에서 시작하는가?*

*2. 빈 배열을 사용하면 어떤 값을 리턴할 것인가?*&#x20;

*3. 비즈니스 규칙이 있는가?*
{% endhint %}
