# ES6+ Basic4

[인프런 함수형 프로그래밍과 JavaScript ES6+](https://inf.run/3PMF) / [유인동](https://www.inflearn.com/users/31989)

### 결과를 만드는 함수 reduce, take

* 실제로 연산을 시작하는 시작점을 알리는 함수

### reduce

```
L.entries = fuction *(obj) {
    for (const k in obj) yield [k, obj[k]];
};

// Array.prototype.join보다 다형성이 높은 join함수
const join = curry((sep = ',', iter) =>
    reduce((a, b) => '${a}${sep}${b}', iter));

// const queryStr = obj => go(
//   obj,
const queryStr = pipe(
    L.entries,
    L.map(([k, v])=> '${k}=${v}'),
    join('&');

//    Object.entries,
//    map(([k, v])=> '${k}=${v}'),
//    reduce((a, b) => '${a}&${b}')
);

log(queryStr({ limit: 10, offset:10, type:'notice'}));
```

### take, find

* find는 take를 통해 결론(결과)을 지어서 만들 수 있음

```
const users = [
    { age: 32 },
    { age: 43 },
    { age: 34 },
    { age: 25 },
    { age: 21 },
    { age: 38 },
    { age: 23 },
];

// 첫번째로 만나는 1개만 꺼내주는 함수
const find = curry((f, iter) => go(
    iter,
    L.filter(f)
    take(1)
    ([a]) => a
));

log(find(u => u.age < 30, users ));
```

### L.map + take로 map 만들기

```
const takeAll = take(Infinity);

L.map = curry(function *(f, iter) {
    for (const a of iter) {
        yield f(a);
    }
});

const map = curry(pipe(L.map, takeAll));

log(map(a => a + 10, L.range(4)));
```

### L.filter + take로 filter 만들기

```
L.filter = curry(fuction *(f, iter) {
    for (const a of iter ) {
        if (f(a)) yield a;
    }
});

const filter = curry(pipe(L.filter, takeAll));

log(filter(a => a % 2, range(4)));
```

### L.flatten

```
// 바로 평가되는 flatten 함수
const flatten = pipe(L.flatten, takeAll);

const isIterable = a => a && a[Symbol.iterator];

// 깊은 Iterable을 모두 펼칠 때
L.deepFlat = function*(iter) {
    for (const a of iter) {
        if (isIterable(a)) yield *f(a);
        else yield a;
    }
}

L.flatten = function *(iter) {
    for (const a of iter) {
        if (isIterable(a)) yield *a;
//        if (isIterable(a)) for (const b of a) yield b;
// yield *iterabel = for (const val of iterable) yield val;
        else yield a;
    }

var it = L.flatten([[1,2], 3, 4, [5, 6], [7, 8, 9]]);
log([...it]);
};
```

* 1차원 배열로 만들어주는 제너레이터를 반환하는 함수

### L.flatMap

```
// 두 방법은 큰 차이가 없음(똑같이 전부 순회하기 때문)
// 기존의 flatmap은 array에서만 동작함
log([1, 2], [3, 4], [5, 6, 7].flatMap(a => a.map(a => a * a)));
log(flatten([1, 2], [3, 4], [5, 6, 7].map(a => a.map(a => a * a))));

L.flatMap = curry(pipe(L.map, L.flatten));

//즉시평가
const flatMap = curry(pipe(L.map, flatten));

var if = L.flatMap(map(a => a * a), [[1, 2], [3, 4], [5, 6, 7]]);
log([...it]);
```

### 2차원 배열 다루기

```
const arr = [
    [1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [9, 10]
];

go(arr,
    L.flatten,
    L.filter(a => a % 2),
    L.map(a => a * a),
    take(3),   
    reduce(add),
    log);
```

### 지연성 / 이터러블 중심 프로그래밍 실무적인 코드 예제

```
var users = [
    { name: 'a', age: 21, family: [
        { name: 'a1', age: 56 }, { name: 'a2', age: 70 },
        { name: 'a3', age: 15 }, { name: 'a4', age: 3 }
    ]},
    { name: 'b', age: 38, family: [
        { name: 'b1', age: 34 }, { name: 'b2', age: 5 }
    ]},
    { name: 'c', age: 31, family: [
        { name: 'c1', age: 68 }, { name: 'c2', age: 62 },
        { name: 'c3', age: 12 }
    ]},
    { name: 'd', age: 20, family: [
        { name: 'd1', age: 42 }, { name: 'd2', age: 42 },
        { name: 'd3', age: 11 }, { name: 'd4', age: 4 }
    ]},
]

go(users,
    L.map(u => u.family),
    L.flatten,
    L.filter(u => u.age < 20),
    L.map(u => u.name),
    take(4),
    log);
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://codekyz0111.gitbook.io/today-i-learned/2022/javascript/es6+-basic/es6+basic-4.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
