javascript - Ramda:如何根据对象的其他值仅更改对象的一个值
问题描述
我正在构建一个 React 应用程序。我正在使用 Ramda 来帮助我进行函数式编程。
如果您想查看完整代码,我还在StackExchange Code Review上寻求帮助。
不过,对于 Stack Overflow,只有一部分是相关的。
如何使用 Ramda 根据对象的其他值更改对象的特定值?我mapObjIndexed
在进程中使用 which 映射所有键。
上下文:我有一个对象代表一个带有几个键的联系人,这些键都是字符串。该对象始终有一个名为 的键contactDetails
。我想计算contactDetails
依赖于对象的值tel
和bday
键email
的值。
如果联系人在函数之前看起来像这样:
{
firstName: 'John',
lastName: 'Doe',
contactDetails: '',
tel: '555-55-5555',
bday: '',
email: 'john@doe.com'
}
之后应该是这样的:
{
firstName: 'John',
lastName: 'Doe',
contactDetails: 'john@doe.com 555-55-5555',
tel: '555-55-5555',
bday: '',
email: 'john@doe.com'
}
我为此编写的函数如下所示:
R.mapObjIndexed((val, key, obj) =>
key === 'contactDetails'
? R.trim(
R.replace(
/undefined/g,
'',
`${R.prop('bday')(obj)} ${R.prop('tel')(obj)} ${R.prop('email')(
obj
)}`
)
)
: val
),
正如您所看到的,这是一种非常不干净和骇人听闻的滥用方式map
。有没有更好的方法来根据对象的其他值更改 Ramda 中的对象的值?
解决方案
除非这是学习 Ramda 的练习,否则我建议比您可能从 Ramda 提出的任何方法更简单的技术是直接的对象解构方法:
const transform = ({tel, bday, email, ...rest}) => ({
...rest, tel, bday, email,
contactDetails: [bday, email, tel].join(' ').trim()
})
const obj = {firstName: 'John', lastName: 'Doe', tel: '555-55-5555', bday: '', email: 'john@doe.com'}
console.log(transform(obj))
这个版本不依赖于contactDetails
已经存在的密钥,尽管它存在也不会受到伤害。
如果您真的担心单词之间可能存在双空格(例如,如果提供了bday
和tel
,但email
为空),您可以将其修改为:
const combine = (ss) => ss.reduce((a, s) => a + (s.length ? ' ' : '') + s, '').trim()
const transform = ({tel, bday, email, ...rest}) => ({
...rest, tel, bday, email,
contactDetails: combine([bday, email, tel])
})
我是 Ramda 的创始人之一,也是我的忠实粉丝,但它只是一个工具包。有很多地方可以帮助您的代码更易于阅读和编写;无论如何都要使用它。但是如果它不这样做,即使在大量使用 Ramda 的代码库中,也可以跳过它并使用其他技术。
推荐阅读
- visual-studio-code - cmd shell 中的 Ctrl+C 导致 VSCode 退出
- macos - 是否可以通过 Applescript 访问 Spotify Mac 应用程序中当前播放歌曲的歌曲名称?
- javascript - 如何通过 event.target 区分同一层中的 react konva 元素?
- c# - C# 不会运行 PowerShell 脚本
- c# - 为什么我的 Web API 没有响应我的请求?
- python - 在python中检查一个字符串是否至少包含五个字符
- java - 如何将 JPA 查询结果映射到 POJO?
- php - 将内联 CSS 添加到 woocommerce 产品列表
- asp.net-mvc - 修改 web.config 文件
- selenium - 硒网格。在各种浏览器中并行执行