compose()について Leetcodeを 使って調べる !!!

>今回はleetcode 2629を使ってcomposeについて調べましょう！

Linkはこちら
https://leetcode.com/problems/function-composition/description/?envType=study-plan-v2&envId=30-days-of-javascript

## leetcode : 2629. Function Composition

### compose()とは?
```typescript
    const addOne = (x: number): number => x + 1;
    const double = (x: number): number => x * 2;
    const square = (x: number): number => x * x;
    
    const composedFunction = compose(addOne, double, square); 
    console.log(composedFunction(x)); // result : (x^2) * 2 + 1 = 9

```

:::note info
出力
result : (x^2) * 2 + 1 = 9
:::

### leetcode : 2629　の正解

```typescript
type F = (x: number) => number;

function compose(functions: F[]): F {
    if (functions.length === 0){
        return function(x){
            return x
        }
    }else{
        return function(x){
            let result : number =x 
            // for (let i = functions.length -1; i>=0; i--){
            //     result = functions[i](result)
            //     console.log(result)
            // }

            functions
            .slice()
            .reverse()
            .forEach((func)=>{
                result = func(result);
                console.log(result);
            });
            return result;
        }
    }
    
};

/**
 * const fn = compose([x => x + 1, x => 2 * x])
 * fn(4) // 9
 */
```
:::note info
forとforEachで具現しました。
速度の差はないので、楽な方で作成してもいいと思います。
:::



### study!
今回のstudy!では実際にありそうなシナリオで持ってきました。
私が今作ってるvtuberの紹介するpageの中でprofile_imageとtitleが必要です。
それで、バックエンドにデータ要請後、必要なデータをパースし、recoilでatomに状態を保存します。
composeを使って具現しましょ。

#### code
```typescript

import { atom, useSetRecoilState } from "recoil";

// 1. Recoil Atom 定理
const imageState = atom({
  key: "imageState",
  default: [],
});

// 2. composeに使うFunctionの定理
const fetchData = async (url: string): Promise<any> => {
  const response = await fetch(url);
  return response.json();
};

const parseData = (data: any): { title: string; image: string }[] => {
  return data.items.map((item: any) => ({
    title: item.title,
    image: item.image,
  }));
};

const setRecoilState =
  (setRecoil: (data: any) => void) =>
  (data: any): void => {
    setRecoil(data);
  };

// 3. Compose Function
type Func<T, R> = (arg: T) => R;

function compose<T>(...functions: Func<any, any>[]): Func<T, any> {
  return (input: T) => functions.reduceRight((acc, func) => func(acc), input);
}

// 4. 使用例
export const useLoadImages = () => {
  const setImageState = useSetRecoilState(imageState);

  const processImages = compose(
    setRecoilState(setImageState), // atomに状態を保存
    parseData,                    // データをパース
    fetchData                     // fetch要請
  );

  //使用する時
  const loadImages = async (url: string) => {
    await processImages(url);
  };

  return loadImages;
};
```
#### 使用方法
```typescript
import { useLoadImages } from "./path/to/above/code";

const Component = () => {
  const loadImages = useLoadImages();

  const handleLoad = () => {
    loadImages("https://api.example.com/data");
  };

  return <button onClick={handleLoad}>Load Images</button>;
};
```


[参考資料]
https://leetcode.com/problems/function-composition/description/?envType=study-plan-v2&envId=30-days-of-javascript


なぜなのかrecoilのjpのpageがいないので韓国のpageを送りします。:scream:

https://recoiljs.org/ko/

### 最後に
日本語の勉強するために作成しておりますので、間違った日本語や内容がありましたらいつでもフィードバックいただければ幸いです。