【问题标题】:Functional programming / Ramda: Creating a new object by picking nested properties函数式编程/ Ramda:通过选择嵌套属性创建一个新对象
【发布时间】:2017-01-04 00:21:30
【问题描述】:

这里是函数式编程新手。我有这个对象:

{ 
  _id: '2014d5db-55dc-4078-ae87-382c226d0785',
  _source: { 
    phone: '00447827434313',
    ...
  } 
}

最后我想用这种格式:

{ 
  id: '2014d5db-55dc-4078-ae87-382c226d0785',
  phone: '00447827434313',
  ...
}

基本上提取_source,并将_id重命名为id

我在下面创建了这个有效的函数,但我尝试只使用 Ramda 的函数而不是手动创建新对象。我认为这是更“实用”的方式,如果它真的不重要,请告诉我。

const test = o => merge(o._source, { id: o._id })

非常感谢

【问题讨论】:

  • 你的输出会一直这样吗? (即没有嵌套属性?)
  • @ScottSauyet 理想情况下是的。我只想在_source 中添加任何内容,并在顶部添加_id,重命名为id

标签: javascript functional-programming ramda.js


【解决方案1】:

我不认为有一个特定的内置 Ramda 函数可以解决这个问题。不过在lensPathviewmap之上写一个也不难:

const remap = R.curry((desc, obj) => R.map(path => R.view(R.lensPath(path), obj), desc));

const myExtract = remap({
  id: ['_id'],
  phone: ['_source', 'phone']
});

myExtract(input);
//=> {"id": "2014d5db-55dc-4078-ae87-382c226d0785", "phone": "00447827434313"}

仅当您的输出被描述为字段的平面列表时才有效(当然它们的属性本身可能是对象。)但是从嵌套路径中拉出并推送到嵌套路径的方法不会太难写。不过,我想用户 API 会更丑。

我没有看到任何干净的方法可以使这个点免费并且仍然保持可读性。也许其他人可能会做到这一点,但我认为这已经很不错了。

您可以在 Ramda REPL 上看到这一点。

【讨论】:

  • 非常感谢@ScottSauyet,这很有帮助。你同意我的test() 功能不是功能性的方式吗?我只是想确保寻找其他东西对我来说是公平的
  • 我不认为有一个单一的答案。您的方法是最直接的方法,如果您不需要更多可重用的方法,为什么不继续使用它呢?如果您希望在映射不同的字段时重用它,我的建议可能是一个改进。如果你想映射到更复杂的结构,那么你需要更复杂的东西。您原来的唯一缺点是它可能包含您不想source 包含的字段。如果这不是问题,它本身就是一个完全有效的解决方案。
猜你喜欢
  • 2018-10-14
  • 2018-01-30
  • 1970-01-01
  • 1970-01-01
  • 2021-10-27
  • 1970-01-01
  • 1970-01-01
  • 2018-01-16
  • 1970-01-01
相关资源
最近更新 更多