Typescript 将数组转换为对象的正确方法

Typescript 将数组转换为对象的正确方法,typescript,functional-programming,fp-ts,Typescript,Functional Programming,Fp Ts,我不熟悉函数式编程,但想学习最佳实践 将数组转换为对象的正确方法是什么 (items:Item[],keyGetter:(i:Item)=>Key=>Record 到目前为止,我使用自己的非fp ts实现: 函数已定义(值:T):值已排除{ 返回值!==未定义; } 类型TIdentifier=字符串|编号; 导出常量arrayToRecord=( arr:T1[], getKeyName?:(项目:T1)=>T2 ):记录=>{ const hasKeyNameGetter=isDefined

我不熟悉函数式编程,但想学习最佳实践

将数组转换为对象的正确方法是什么

(items:Item[],keyGetter:(i:Item)=>Key=>Record

到目前为止,我使用自己的非fp ts实现:

函数已定义(值:T):值已排除{
返回值!==未定义;
}
类型TIdentifier=字符串|编号;
导出常量arrayToRecord=(
arr:T1[],
getKeyName?:(项目:T1)=>T2
):记录=>{
const hasKeyNameGetter=isDefined(getKeyName);
返回arr.reduce((附件,项目)=>{
行政协调会[
hasKeyNameGetter?(getKeyName作为(项目:T1)=>T2)(项目):((项目作为未知项)作为T2)
]=项目;
返回acc;
},{}作为记录);
};

这里有一种方法可以实现您的要求

一些注意事项:

  • 由于字典是在运行时生成的,并且对键没有保证,为了防止不安全的代码,返回类型是
    Record
  • keyGetter
    不能是可选的,我们必须提供一种方法来实现e键
import*作为来自“fp ts/ReadonlyArray”的
从“fp ts/ReadonlyRecord”以R形式导入*
从“fp ts/function”导入{pipe}
常量数组记录=(
项目:ReadonlyArray,
keyGetter:(i:A)=>字符串,
):Readonly=>
烟斗(
项目,
A.reduce({},(acc,item)=>管道(acc,R.upsertAt(keyGetter(item),item)),
)
编辑

请举一个例子:

constxs=[
{id:'abc',日期:new date()},
{id:'snt',日期:new date()},
]
常数res=arrayToRecord(xs,(x)=>x.id)
console.log(res)
// {
//abc:{id:'abc',日期:2021-04-06T13:09:25.732Z},
//snt:{id:'snt',日期:2021-04-06T13:09:25.732Z}
// }
编辑2

管道
友好版:

声明常量数组记录:(
keyGetter:(i:A)=>字符串,
)=>(项目:ReadonlyArray)=>只读
接口X{id:string;日期:date}
声明常量xs:ReadonlyArray
烟斗(
xs,
arrayToRecord((x)=>x.id),
)//只读

请提供可复制的示例什么?我的arrayToRecord函数的fp ts等效值?这就是IDK如何实现TIdentifier示例的定义。你的代码不可复制我明白了,对不起。我已经扩展了我的示例
项,将其扩展为未知项T2
功能不强:-)如果您真的需要它,我建议您将函数重载为
(items:Key[])=>Record
。谢谢!你能用用例扩展你的答案吗,比如把这个功能投入工作。假设我们有一个项目数组和keyGetter fn,那么如何将其放入管道fp ts中?@DmitriiBykov我已经添加了它。我可以看到您的编辑,但我的意思是另一件事。如何在管道和fp ts中的其他东西中使用它?如果您希望该函数是“管道友好的”,您必须将其类型签名更改为
(keyGetter:(i:A)=>string)=>(items:ReadonlyArray)=>Readonly
用法:
管道(xs,arrayToRecord((x)=>x.id))
我看不到任何方法来获得这个
管道(xs,keyGetter,arrayToRecord)
(实际上我不明白你为什么要做这个练习)。此外,
fp-ts
充满了高阶函数,所以你通常会得到这样的结果,例如:
pipe(O.some(1),O.map(n=>n+1),O.chain((n=>n%2==0?O.some(n):O.none))