我正在尝试学习Ramda,但在文档中找不到与Lodash _.transform
函数等效的函数:
_.transform([2, 3, 4], function(result, n) {
result.push(n *= n);
return n % 2 == 0;
}, []);
// => [4, 9]
答案 0 :(得分:1)
根据我的见解,_.transform
与Array#reduce
相似,只是它可以被打断:
_.transform([2, 3, 4], function(result, n) {
result.push(n *= n);
return n % 2 == 0;
}, []);
// => [4, 9]
使用Ramda,您可以使用reduce
做同样的事情:
迭代器函数接收两个值:(acc,值)。可以使用R.reduced来简化迭代。
在Ramda中,上面的代码为:
const transform =
reduce((acc, x) =>
(x % 2 ? reduced : identity)
([...acc, x * x]), []);
transform([2, 3, 4]);
//=> [4, 9]
您使用reduced
将累加器acc
包装在一个特殊的对象中,该对象告诉Ramda的reduce
函数来简化迭代。
identity
函数返回其参数。例如identity(42) === 42
。
所以基本上我每次迭代都在做:
reduced
还是identity
?[...acc, x * x]
调用该函数使用伪代码:
( stop ? reduced OR identity )(next_accumulator_value)
答案 1 :(得分:1)
否,如果我正确理解该功能。 Ramda可能永远不会对此行为感兴趣。实际上,当人们尝试对Ramda做类似的事情时,他们最终会感到沮丧。 (免责声明:我是Ramda的核心贡献者之一。)
customcommander所指的似乎是Ramda确实处理的_.transform
的一个功能-提前退出。使用reduced
可以实现这一点,但是我也很少使用它。
但是提供给它的函数的全部要点(用lodash的术语iteratee
)是使累加器对象突变。除非您通过返回end the madness
发送false
信号,否则它的返回将被忽略。而且实际上只有它的副作用很重要。
Ramda旨在避免突变。当您使用Ramda的reduce
折叠到列表时,强烈希望使用concat
而不是push
;换句话说,您不会更改输入。 Ramda并没有采取任何措施来强制执行此操作,并且出于性能原因有时会避开这种期望,但是您可能必须在两次调用之间共享累加器时要小心。但是Ramda当然不可能使它变得更容易。任何仅用于其副作用的功能都会对Ramda造成反感。 (请不要让我想起forEach
!“ foolish consistency是小头脑的妖精。”)
请注意,customcommander的答案并未尝试更改acc
值,而是返回了一个新值:这是非常惯用的Ramda。
如果没有提供,lodash创建初始累加器的意愿也非常不同。 Ramda不允许使用任何可选参数。它们只是不同的设计。
重要的一点是,没有特别的理由期望每个lodash函数都具有Ramda等效项。 Ramda是独立开发的,旨在针对不同的编码风格,受不同的约束,并且从未设计为直接替代。因此,它与lodash的关系与lodash与Underscore的关系非常不同。
它们重叠的程度和它们的重叠程度足以证明两者都支持的许多功能的基本性质。当然,还有一个不可回避的反馈循环,人们从一个库中请求另一个库中的功能。但我认为,仅广泛需要的许多功能就更为重要。