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

时间:2019-12-16 17:28:20

标签: javascript functional-programming ramda.js folktale

我想将不同的功能应用于某些对象属性。可以说我有这个对象:

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的示例,我将不胜感激,谢谢!

2 个答案:

答案 0 :(得分:3)

使用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>


无点样式不是唯一的方法

⚠️

请注意,我已经能够实现这种无点样式,因为我可以对每个转换函数进行硬编码。如果您需要即时制作转换对象,则这种无点样式可能很快就会变得难以理解。

答案 1 :(得分:2)

与往常一样,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函数:toUpperaddappend(比{{3} }。

可以在prepend中找到有关注释中提出的VLAZ主题的更完整讨论。