我现在正在学习JS库Ramda。而且似乎有一种模式我无法正确解决。例如,我有此代码。
const filterPayments = filter => payments =>
r.filter(
r.allPass([
typePred(filter),
amountPred(filter),
accountPred(filter),
currencyPred(filter)
]),
payments
);
现在这似乎是一种情况,在此情况下,我并不是不愿意让它变得毫无意义。我似乎找不到正确的方法。
此外,我在使像这样的逻辑功能完全可用且没有点数方面遇到麻烦:
const amountPred = filter => p =>
r.and(p.betrag >= filter.amount.min, p.betrag <= filter.amount.max);
也许有人可以为我指明正确的方向或提供一些指导?
答案 0 :(得分:2)
我将提供的指导是坚持您当前拥有的:)
我可以向您展示一个示例,说明您所拥有内容的无点翻译是什么样子,尽管所得到的代码非常可怕,而且仅对一次精神体操有益。
首先,payments
出现在函数表达式两边的最终位置,因此我们可以简单地将其删除。
const filterPayments = filter =>
R.filter(
R.allPass([
typePred(filter),
amountPred(filter),
accountPred(filter),
currencyPred(filter)
]));
接下来,我们可以看一下传递给R.allPass
的函数列表
R.allPass(R.map(p => p(filter), [typePred, amountPred, accountPred, currencyPred]))
现在,我们可以通过翻转filter
将其推到末尾来开始删除R.map
自变量。
R.allPass(R.flip(R.map)([typePred, amountPred, accountPred, currencyPred])(p => p(filter))
现在让我们制作filter
和p => p(filter)
的参数,而不是关闭它,使其成为:
R.allPass(R.flip(R.map)
([typePred, amountPred, accountPred, currencyPred])
(R.applyTo(filter)))
现在h(g(f(a)))
开始成形,我们可以使用R.pipe
,R.compose
,R.o
等将其转换为无点。
const filterPayments = R.compose(
R.filter,
R.allPass,
R.flip(R.map)([typePred, amountPred__, accountPred, currencyPred]),
R.unary(R.applyTo) // R.unary is needed here to tell Ramda only to expect the first argument in this composition
)
这为我们提供了一个功能,该功能现在应该等效于您的filterPayments
(无点形式)。
您的amountPred
示例变得更加复杂,我想您以后会同意,您已经拥有的是两者之间更好的选择。
同样,我们首先尝试将参数推到表达式每一边的末尾:
filter => p =>
both(
x => x >= filter.amount.min,
x => x <= filter.amount.max
)(p.betrag)
然后我们可以放下p
:
filter => R.o(
both(
x => x >= filter.amount.min,
x => x <= filter.amount.max
),
prop('betrag'))
传递给both
的函数也可以换出:
filter => R.o(
both(
R.flip(R.gte)(filter.amount.min),
R.flip(R.lte)(filter.amount.max)
),
prop('betrag'))
现在要解决filter
,我们可以使用R.converge
将相同的参数传递给多个函数,然后将每个函数的结果合并在一起。
filter => R.o(
R.converge(both, [
f => R.flip(R.gte)(R.path(['amount', 'min'], f),
f => R.flip(R.lte)(R.path(['amount', 'max'], f)
])(filter),
prop('betrag'))
现在f
处于结束位置,因此可以按组成将其删除:
filter => R.o(
R.converge(both, [
R.o(R.flip(R.gte), R.path(['amount', 'min'])),
R.o(R.flip(R.lte), R.path(['amount', 'max']))
])(filter),
prop('betrag'))
最后将filter
弄得很混乱,涉及到翻转合成函数。
filter => R.o(
R.flip(R.o)(R.prop('betrag')),
R.converge(both, [
R.o(R.flip(R.gte), R.path(['amount', 'min'])),
R.o(R.flip(R.lte), R.path(['amount', 'max']))
])
)(filter)
最后...
const amountPred = R.o(
R.flip(R.o)(R.prop('betrag')),
R.converge(both, [
R.o(R.flip(R.gte), R.path(['amount', 'min'])),
R.o(R.flip(R.lte), R.path(['amount', 'max']))
])
)
...将其与您的原始内容进行比较,我知道我更喜欢阅读以下内容:
const amountPred = filter => p =>
p.betrag >= filter.amount.min && p.betrag <= filter.amount.max
答案 1 :(得分:0)
我已经开始做和Scott Christopher一样的工作,并且将主要功能重构为无点,从一开始就知道我的建议几乎肯定不会为此而烦扰。我找到了我的无点版本,它比我预期的要简单。在开始谓词之前,我曾想过看看Scott的解决方案。
他做了我会做的很多事情,而且可能比我做的更好。当然,他以类似的建议告终。我总是试图建议人们不要出于无聊而迷恋。当它使您的代码更简洁易懂时,请使用它。不用时不要使用它。
我什么都不会回答,只是我最终得到了一个更好的主函数无点版本,并且想考虑一下:
const filterPayments = pipe(
juxt([typePred, amountPred, accountPred, currencyPred]),
allPass,
filter
)
尽管这很干净,但我认为它的可读性不如您的原著,因此我不建议您这样做。但是,如果您真的想要无积分,那就有可能。