【发布时间】:2018-10-03 10:40:14
【问题描述】:
给定一个可能为空且可能具有以下属性的对象:
{
templateId: "template1",
templates: {
template1: "hello"
}
}
如何以故障安全的方式获取模板? (可能没有定义templateId,或者它引用的模板可能未定义)
我使用 ramda 并试图调整我的原始代码版本以使用可能的广告来避免显式的空/未定义检查。
我没有想出一个优雅而干净的解决方案。
朴素的 ramda 版本:
const getTemplate = obj => {
const templateId = obj && prop("templateId", obj);
const template = templateId != null && path(["template", templateId], obj);
return template;
}
这确实有效,但我想避免空值检查,因为我的代码还有很多事情要做,而且变得更干净会非常好
编辑 我从几个答案中得到最好的答案是首先确保数据干净。 但这并不总是可能的。 我也想出了这个,我很喜欢。
const Empty=Symbol("Empty");
const p = R.propOr(Empty);
const getTemplate = R.converge(p,[p("templateId"), p("templates")]);
希望获得有关它的干净程度和可读性的反馈(以及是否存在会破坏它的边缘情况)
【问题讨论】:
-
“给定一个可能为空且可能具有以下属性的对象”排除了“干净”解决方案的可能性。 :P
-
每个人都在指出您的输入数据如何成为问题。他们是对的。但是我经常要处理这样的数据,来自遗留系统,来自很久以前被大型企业选择的第三方供应商提供的不一致的 API,来自另一个团队中不了解如何正确使用的初级开发人员来自各种地方的错误响应或空值。你的目标是解决这个问题。如果你有这样的数据,也许你自己的第一步就是清理它。如果您以
map(defaultTo({templates: []}))开头,您将消除您的几个nil检查。 -
抱歉,
map是我自己解决问题的方法,不值得发帖。我使用了来自 user633183 的解决方案中的值列表。根据您的解决方案,您可能只使用其中的defaultTo部分。 -
我明白了@davidchambers、@scott-sauyet、@user633183 感谢您的回答,感谢您抽出宝贵的时间!我喜欢这种解决方案:
const Empty=Symbol("Empty"); const p = R.propOr(Empty);const getTemplate = R.converge(p,[p("templateId"), p("templates")]);,但我真的很想得到像你这样有经验和聪明的人的意见,因为我觉得它有点难以阅读。
标签: javascript functional-programming ramda.js sanctuary