如何将对象的属性应用于函数?
How to apply properties of an object to functions?
我想对某些对象属性应用不同的函数。假设我有这个对象:
const person = {
name: 'John',
age: 30,
friends: [],
};
并且我有一些函数要应用于这些属性:
const upperCase = str => str.toUpperCase() //for the name
const add10 = int => int + 10 // for the age
const addFriend = (value,list) => [...list,value] // adding a friend
这应该是结果:
const person = {
name: 'JOHN',
age: 40,
friends: ['Lucas']
}
使用函数式编程和 point free 实现此目的的最佳方法是什么,如果您可以包含使用 Ramda 的示例,我将不胜感激,谢谢!
使用 Ramda,您正在查看 evolve
函数:
Creates a new object by recursively evolving a shallow copy of object, according to the transformation functions. All non-primitive properties are copied by reference.
您可能需要即时定义 "transform" 函数;我打赌你不想将 'Lucas' 添加为每个人的朋友。希望这足以让您入门。
const transform =
evolve(
{ name: toUpper
, age: add(10)
, friends: prepend('Lucas')
});
console.log(
transform(person)
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
<script>const {evolve, toUpper, add, prepend} = R;</script>
<script>
const person =
{ name: 'John'
, age: 30
, friends: []
};
</script>
无点风格不是唯一的方式
⚠️
请注意,我已经能够实现这种无点样式,因为我可以对每个转换函数进行硬编码。如果您需要即时制作一个转换对象,那么这样做的无点样式可能很快就变得不可读了。
像往常一样,customcommander 给出了很好的答案。 Ramda 的 evolve
正是为此而设计的,在简单的情况下,可以提供完全无意义的答案。
Ramda的作者之一,非常喜欢它的功能。但应该注意的是,构建您自己的许多版本非常容易,包括这个版本,特别是如果您处于只关心更新对象根目录中的键的简单情况。 (Ramda 的递归成嵌套的 spec 对象,这至少有点复杂。)
因此,如果您手边没有 Ramda,您可以像这样轻松编写此函数的自定义版本:
const evolve = (spec, keys = Object .keys (spec)) => (obj) =>
Object .entries (obj) .reduce (
(a, [k, v]) => ({...a, [k]: keys .includes (k) ? spec [k] (v) : v})
, {}
)
const upperCase = str => str.toUpperCase() //for the name
const add10 = int => int + 10 // for the age
const addFriend = (value) => (list) => [...list,value] // adding a friend
const person = {name: 'John', eys: 'blue', age: 30, friends: [], hair: 'red'}
console .log (
evolve ({name: upperCase, age: add10, friends: addFriend('Lucas')}) (person)
)
这远不是性能最高的代码。 Rich Snapp 的一篇优秀文章解释了为什么以及如何修复它。但我个人会坚持这样做,除非这成为我应用程序的瓶颈。
当然,正如 customcommander 也指出的那样,您的每个助手都有 Ramda 函数:toUpper
, add
, append
(closer to the above implementation than prepend
。)
关于评论中提出的 VLAZ 主题的更完整讨论可以在 中找到。
我想对某些对象属性应用不同的函数。假设我有这个对象:
const person = {
name: 'John',
age: 30,
friends: [],
};
并且我有一些函数要应用于这些属性:
const upperCase = str => str.toUpperCase() //for the name
const add10 = int => int + 10 // for the age
const addFriend = (value,list) => [...list,value] // adding a friend
这应该是结果:
const person = {
name: 'JOHN',
age: 40,
friends: ['Lucas']
}
使用函数式编程和 point free 实现此目的的最佳方法是什么,如果您可以包含使用 Ramda 的示例,我将不胜感激,谢谢!
使用 Ramda,您正在查看 evolve
函数:
Creates a new object by recursively evolving a shallow copy of object, according to the transformation functions. All non-primitive properties are copied by reference.
您可能需要即时定义 "transform" 函数;我打赌你不想将 'Lucas' 添加为每个人的朋友。希望这足以让您入门。
const transform =
evolve(
{ name: toUpper
, age: add(10)
, friends: prepend('Lucas')
});
console.log(
transform(person)
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
<script>const {evolve, toUpper, add, prepend} = R;</script>
<script>
const person =
{ name: 'John'
, age: 30
, friends: []
};
</script>
无点风格不是唯一的方式
⚠️
请注意,我已经能够实现这种无点样式,因为我可以对每个转换函数进行硬编码。如果您需要即时制作一个转换对象,那么这样做的无点样式可能很快就变得不可读了。
像往常一样,customcommander 给出了很好的答案。 Ramda 的 evolve
正是为此而设计的,在简单的情况下,可以提供完全无意义的答案。
Ramda的作者之一,非常喜欢它的功能。但应该注意的是,构建您自己的许多版本非常容易,包括这个版本,特别是如果您处于只关心更新对象根目录中的键的简单情况。 (Ramda 的递归成嵌套的 spec 对象,这至少有点复杂。)
因此,如果您手边没有 Ramda,您可以像这样轻松编写此函数的自定义版本:
const evolve = (spec, keys = Object .keys (spec)) => (obj) =>
Object .entries (obj) .reduce (
(a, [k, v]) => ({...a, [k]: keys .includes (k) ? spec [k] (v) : v})
, {}
)
const upperCase = str => str.toUpperCase() //for the name
const add10 = int => int + 10 // for the age
const addFriend = (value) => (list) => [...list,value] // adding a friend
const person = {name: 'John', eys: 'blue', age: 30, friends: [], hair: 'red'}
console .log (
evolve ({name: upperCase, age: add10, friends: addFriend('Lucas')}) (person)
)
这远不是性能最高的代码。 Rich Snapp 的一篇优秀文章解释了为什么以及如何修复它。但我个人会坚持这样做,除非这成为我应用程序的瓶颈。
当然,正如 customcommander 也指出的那样,您的每个助手都有 Ramda 函数:toUpper
, add
, append
(closer to the above implementation than prepend
。)
关于评论中提出的 VLAZ 主题的更完整讨论可以在