0

我想对某些对象属性应用不同的功能。假设我有这个对象:

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']
}

使用函数式编程和无点实现这一目标的最佳方法是什么,如果您可以包含使用 Ramda 的示例,我将不胜感激,谢谢!

4

2 回答 2

4

使用 Ramda,您正在查看evolve函数:

根据转换函数,通过递归演化对象的浅表副本来创建新对象。通过引用复制所有非原始属性。

您可能需要动态定义“转换”函数;我敢打赌,您不想将“卢卡斯”添加为每个人的朋友。希望这足以让您入门。

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>


无点风格不是唯一的方法

⚠️

请注意,我已经能够实现这种无点样式,因为我可以对每个转换函数进行硬编码。如果您需要即时制作转换对象,那么无点样式可能很快就无法阅读。

于 2019-12-16T17:53:47.700 回答
3

像往常一样,customcommander 给出了一个很好的答案。Ramda'sevolve正是为此而设计的,在简单的情况下,它可以提供完全无点的答案。

Ramda 的作者之一,我非常喜欢它的功能。但应该注意的是,构建自己的许多版本非常容易,包括这个版本,特别是如果您处于只关心更新对象根目录中的键的简单情况下。(Ramda 递归到嵌套的规范对象中,这至少涉及更多。)

所以,如果你手边没有 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(比上述实现更接近prepend。)

可以在https://stackoverflow.com/a/33130194/1243641中找到关于评论中提出的主题 VLAZ 的更完整讨论。

于 2019-12-16T21:05:15.970 回答