【发布时间】:2018-04-25 08:00:07
【问题描述】:
以下面的命令式 JavaScript 示例为例:
getAnimalList = (hasCat) => {
const baseAnimals = { dog: animLib.dog(), bear: animLib.bear()};
if(hasCat){
baseAnimals.cat = animLib.cat();
}
return baseAnimals
}
我正在尝试使用 Ramda 以函数式风格编写此代码,但我可以这样做的唯一方法是让函数超出范围:
getAnimalList = (hasCat) => {
const baseAnimals = { dog: animLib.dog(), bear: animLib.bear()};
return when(always(hasCat), merge({hasCat: animLib.cat()}))(baseAnimals)
}
撇开animLib 超出范围,我要解决的方法是让hasCat 从外部传递(如果这是个问题)如下:
getAnimalList = (hasCat) => {
const baseAnimals = { dog: animLib.dog(), bear: animLib.bear()};
const mergeCat = when(compose(equals(true), prop('hasCat')),
compose(merge({hasCat: animLib.cat()}), prop('baseAnimals')));
return mergeCat({hasCat: hasCat, baseAnimals: baseAnimals});
}
但这使得代码非常冗长。有一个更好的方法吗?或者冗长只是保持代码更纯净的代价。
【问题讨论】:
-
写
getAnimalList = (hasCat) => ({ dog: animLib.dog(), bear: animLib.bear(), cat: hasCat ? animLib.cat() : undefined }). -
您的第二个 sn-p 似乎错过了将
baseAnimals传递给merge的机会。 -
"我会解决 hasCat 从外部传递的问题" - 不,我不明白你的问题是什么。
-
它使代码更难重用。合并 cat 对象的组合函数不能轻易移动到其他地方,因为它依赖于定义的
hasCat。此外,您的第一条评论将不起作用,因为如果hasCat == false我们不希望 cat 作为对象的属性 -
@ScottSauyet 啊,你可能是对的。在这种情况下,
["dog", "bear", "cat"].reduce((dict, name) => ({[name]: animLib[name](), ...dict}), {})可能是最好的方法,并且有条件地将cat放入原始列表中
标签: javascript functional-programming composition ramda.js