今回はleetcode 2629を使ってcomposeについて調べましょう!
leetcode : 2629. Function Composition
compose()とは?
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
出力
result : (x^2) * 2 + 1 = 9
leetcode : 2629 の正解
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
*/
forとforEachで具現しました。
速度の差はないので、楽な方で作成してもいいと思います。
study!
今回のstudy!では実際にありそうなシナリオで持ってきました。
私が今作ってるvtuberの紹介するpageの中でprofile_imageとtitleが必要です。
それで、バックエンドにデータ要請後、必要なデータをパースし、recoilでatomに状態を保存します。
composeを使って具現しましょ。
code
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;
};
使用方法
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>;
};
なぜなのかrecoilのjpのpageがいないので韓国のpageを送りします。
最後に
日本語の勉強するために作成しておりますので、間違った日本語や内容がありましたらいつでもフィードバックいただければ幸いです。