使用Ramda按对象数组属性复制对象的优化需求
重构你的对象拆分函数:更清晰的纯函数实现
看起来你需要把带有数组属性的对象,按数组元素拆分成多个独立对象,同时保持其他属性不变,而且想要一个清晰、纯函数的实现对吧?我来帮你重构一下,不管是用Ramda还是原生JS都能搞定~
用Ramda实现的纯函数方案
Ramda本身就推崇纯函数和不可变性,我们可以利用它的工具函数写出简洁且清晰的代码:
const duplicateByLocales = R.curry((propName, obj) => { // 获取目标数组属性的值 const items = R.prop(propName, obj); // 遍历数组每个元素,为每个元素创建新对象(原对象不会被修改) return R.map(item => R.assoc(propName, [item], obj), items); });
代码解释
R.curry:让函数支持柯里化,你可以先指定要拆分的属性名(比如'locales'),再传入目标对象,复用性更强;R.prop:安全地获取对象的指定属性值,避免属性不存在时出错;R.map:遍历数组元素,为每个元素生成新对象;R.assoc:创建一个新对象,替换指定属性的值为[item],不会修改原对象,保证了纯函数的特性。
测试示例
const input = { url: 'getting-started', locales: ['en-GB', 'en-JP'] }; const result = duplicateByLocales('locales')(input); // 输出结果和预期一致: // [{ url: 'getting-started', locales: ['en-GB'] }, { url: 'getting-started', locales: ['en-JP'] }]
原生JS的纯函数方案
如果不想依赖Ramda,用原生JS也能写出同样清晰的纯函数:
function duplicateByProp(propName, obj) { // 先浅拷贝原对象,避免修改原输入 const baseObj = { ...obj }; const items = baseObj[propName]; // 遍历数组,为每个元素生成包含单个元素数组的新对象 return items.map(item => ({ ...baseObj, [propName]: [item] })); }
代码解释
- 用扩展运算符
{ ...obj }浅拷贝原对象,确保原对象不会被修改; Array.map遍历数组元素,每个元素返回一个新对象,继承原对象的所有属性,同时覆盖目标属性为单个元素的数组;- 整个函数没有副作用,输入相同的参数一定会得到相同的输出,符合纯函数的定义。
测试示例
const input = { url: 'getting-started', locales: ['en-GB', 'en-JP'] }; const result = duplicateByProp('locales', input); // 同样得到预期的输出
这两个方案都比你原来的实现更清晰,逻辑一目了然,而且都是纯函数,不会对输入对象造成任何修改~
内容的提问来源于stack exchange,提问作者Deniz Ozger
相关产品推荐
相关产品推荐

