Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/468.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何将对象的属性应用于函数?_Javascript_Functional Programming_Ramda.js_Folktale - Fatal编程技术网

Javascript 如何将对象的属性应用于函数?

Javascript 如何将对象的属性应用于函数?,javascript,functional-programming,ramda.js,folktale,Javascript,Functional Programming,Ramda.js,Folktale,我想对一些对象属性应用不同的函数。假设我有一个对象: const person={ 姓名:'约翰', 年龄:30,, 朋友们:[], }; 我想对这些属性应用一些函数: const upperCase=str=>str.toUpperCase()//名称 const add10=int=>int+10//表示年龄 const addFriend=(值,列表)=>[…列表,值]//添加朋友 结果应该是: const person={ 姓名:'约翰', 年龄:40,, 朋友:[“卢卡斯”] }

我想对一些对象属性应用不同的函数。假设我有一个对象:

const person={
姓名:'约翰',
年龄:30,,
朋友们:[],
};
我想对这些属性应用一些函数:

const upperCase=str=>str.toUpperCase()//名称
const add10=int=>int+10//表示年龄
const addFriend=(值,列表)=>[…列表,值]//添加朋友
结果应该是:

const person={
姓名:'约翰',
年龄:40,,
朋友:[“卢卡斯”]
}

使用函数式编程和无点编程实现这一点的最佳方法是什么?如果您能提供使用Ramda的示例,我将不胜感激,谢谢

使用Ramda,您将看到函数:

根据变换函数,通过递归演化对象的浅层副本来创建新对象。所有非基本属性都是通过引用复制的

您可能需要动态定义“转换”函数;我打赌你不想加上卢卡斯作为每个人的朋友。希望这足以让你开始

const变换=
进化(
{姓名:图珀
,年龄:加(10)
,朋友:prepend('Lucas')
});
console.log(
转化(人)
);

const{evolve,toUpper,add,prepend}=R;
警察=
{姓名:'约翰'
,年龄:30
,朋友:[]
};

像往常一样,customcommander给出了一个极好的答案。拉姆达的
evolve
正是为了实现这一点而设计的,在简单的情况下,它可以提供一个完全无点的答案

拉姆达的作者之一,我非常喜欢它的功能。但需要注意的是,构建自己的许多版本(包括本版本)非常容易,特别是在只关心更新对象根上的键的简单情况下。(Ramda递归到嵌套的等级库对象中,这至少有点复杂。)

因此,如果您手头没有Ramda,您可以很容易地编写此函数的自定义版本,如下所示:

const evolve=(spec,key=Object.key(spec))=>(obj)=>
Object.entries(obj).reduce(
(a[k,v])=>({…a[k]:键。包括(k)?规范[k](v):v})
, {}
)
const upperCase=str=>str.toUpperCase()//用于名称
const add10=int=>int+10//表示年龄
const addFriend=(值)=>(列表)=>[…列表,值]//添加朋友
const person={name:'John',eys:'blue',年龄:30岁,朋友:[],头发:'red'}
控制台日志(
进化({姓名:大写,年龄:add10,朋友:addFriend('Lucas')})(person)

)
调用对象成员上的每个函数。Ramda和Folktale在函数编程方法上大不相同。这并不是说它们是关于“不同的”函数式编程,而是关于它的不同方面。Ramda为您提供函数式的助手函数,如
R.map
R.flip
R.compose
等。而民间故事则实现了诸如Functor、Monad、Applicative、Grupoid等代数类型。这两个函数实际上并不可互换,但可以一起使用。@MaihanNijat我知道我可以调用对象上的每个函数,一次一个,但是有没有一种方法可以同时应用所有这些函数,并保持函数的纯净?@davidstivendangel为所有这些函数创建一个包装函数,并且只调用一次。@MaihanNijat我想我知道如何使用常规调用。我更新了问题,所以答案也包括了无分。我一直在寻找的是ThanksThanks,它不仅是reduce-spread反模式,而且作为
push
/
unshift
使用的
concat
也是有害的,因为它将数组视为持久数据结构。@bob:但除非它成为我的实际性能问题,为了尽可能多地使用表达式而不是语句,我将接受这一点作为权衡。(或者你有一种基于表达式的方法可以避免这种情况吗?)有很多很好的工具告诉我,类似这样的东西在我的应用程序中是一个瓶颈。但我已经好几年没用过了。即使以这种风格写作,我通常也能达到我的速度目标,而速度的下降几乎总是由于IO,而不是这样的结构。也许有一天我会为此而诅咒自己。在99%的情况下,绩效惩罚可能可以忽略不计。然而,我认为将数组作为必要的数据结构来处理是一个很好的工程,即局部突变不仅是OK,而且是默认的。我使用了两个库函数,它们允许突变,并且仍然是可组合的。和往常一样,这是一种权衡。对于
Object
s,这是不同的,因为它们与镜头一起使用时具有固有的持久性。@bob:我不理解你对阵列和对象进行不同处理的理由。我两种镜头都用。我当然有时会在函数边界内使用数据结构的变异,但通常会感觉有点脏。我越是尝试合并表达式而不是语句代码,我就越有可能接受这种性能不佳的模式,除非我看到可测量的危害。
对象与镜头一起使用时本质上是持久的,因为只有属性本身及其根路径是在更新时创建的,而其他所有内容都是共享的。使用数组时,必须创建整个
数组
,即使只更新一个元素。这是因为数组本质上是非持久的。这有什么意义吗?有希望地