Ramda 中 Lodash _.transform 的等价物是什么?
What is the equivalent of Lodash _.transform in Ramda?
我正在尝试学习 Ramda,但我在文档中找不到它与 Lodash _.transform
函数的等效项:
_.transform([2, 3, 4], function(result, n) {
result.push(n *= n);
return n % 2 == 0;
}, []);
// => [4, 9]
据我所知_.transform
和Array#reduce
类似,只是可以打断:
_.transform([2, 3, 4], function(result, n) {
result.push(n *= n);
return n % 2 == 0;
}, []);
// => [4, 9]
使用 Ramda,您可以使用 reduce
做同样的事情:
The iterator function receives two values: (acc, value). It may use R.reduced to shortcut the iteration.
在 Ramda 中,上面的代码将是:
const transform =
reduce((acc, x) =>
(x % 2 ? reduced : identity)
([...acc, x * x]), []);
transform([2, 3, 4]);
//=> [4, 9]
您使用 reduced
将累加器 acc
包装在一个特殊对象中,该对象告诉 Ramda 的 reduce
函数缩短迭代。
identity
函数returns其参数。例如identity(42) === 42
.
基本上我在每次迭代中所做的是:
- 我需要什么功能?
reduced
或 identity
?
- 然后用
[...acc, x * x]
调用那个函数
在伪代码中:
( stop ? reduced OR identity )(next_accumulator_value)
不,如果我理解正确的话。 Ramda 可能永远不会对这种行为感兴趣。事实上,当人们试图用 Ramda 做类似的事情时,他们往往会以失败告终。 (免责声明:我是 Ramda 的核心贡献者之一。)
customcommander 指出的似乎是 Ramda 确实设法处理的 _.transform
的一个功能——提前退出。使用 reduced
使这成为可能,但我也很少使用它。
但是提供给它的函数的全部要点(lodash 术语中的 iteratee
)是改变累加器对象。它的 return 将被忽略,除非您通过 returning false
发送 end the madness
信号。只有它的副作用才是真正重要的。
Ramda 是围绕避免突变而设计的。当你使用 Ramda 的 reduce
折叠到一个列表时,强烈的期望是你会使用 concat
而不是 push
;换句话说,您不会改变输入。 Ramda 没有强制执行这一点,有时出于性能原因回避这种期望,但是你可能必须小心在调用之间共享累加器。但 Ramda 肯定不会让它变得更容易。任何旨在仅用于其副作用的函数都是 Ramda 的诅咒。 (请不要提醒我forEach
!"A foolish consistency is the hobgoblin of little minds.")
请注意,customcommander 的回答并未尝试改变 acc
值,而是 return 编辑了一个新值:这是非常惯用的 Ramda。
另外一个非常不同的是 lodash 愿意在没有提供初始累加器的情况下创建一个初始累加器。 Ramda 不允许任何可选参数。它们只是不同的设计。
重要的一点是,没有特别的理由期望每个 lodash 函数都有一个 Ramda 等价物。 Ramda 是独立开发的,针对不同的编码风格,受制于不同的约束,并且从未设计为直接替代品。所以它与 lodash 的关系与 lodash 与 Underscore 的关系非常不同。
它们的重叠程度与它们的重叠程度一样多,这证明了两者都支持的许多功能的基本性质。当然,还有一个不可忽视的反馈循环,即人们从一个图书馆请求另一个图书馆的功能;但我认为很多功能只是被广泛需要更为重要。
我正在尝试学习 Ramda,但我在文档中找不到它与 Lodash _.transform
函数的等效项:
_.transform([2, 3, 4], function(result, n) {
result.push(n *= n);
return n % 2 == 0;
}, []);
// => [4, 9]
据我所知_.transform
和Array#reduce
类似,只是可以打断:
_.transform([2, 3, 4], function(result, n) {
result.push(n *= n);
return n % 2 == 0;
}, []);
// => [4, 9]
使用 Ramda,您可以使用 reduce
做同样的事情:
The iterator function receives two values: (acc, value). It may use R.reduced to shortcut the iteration.
在 Ramda 中,上面的代码将是:
const transform =
reduce((acc, x) =>
(x % 2 ? reduced : identity)
([...acc, x * x]), []);
transform([2, 3, 4]);
//=> [4, 9]
您使用 reduced
将累加器 acc
包装在一个特殊对象中,该对象告诉 Ramda 的 reduce
函数缩短迭代。
identity
函数returns其参数。例如identity(42) === 42
.
基本上我在每次迭代中所做的是:
- 我需要什么功能?
reduced
或identity
? - 然后用
[...acc, x * x]
调用那个函数
在伪代码中:
( stop ? reduced OR identity )(next_accumulator_value)
不,如果我理解正确的话。 Ramda 可能永远不会对这种行为感兴趣。事实上,当人们试图用 Ramda 做类似的事情时,他们往往会以失败告终。 (免责声明:我是 Ramda 的核心贡献者之一。)
customcommander 指出的似乎是 Ramda 确实设法处理的 _.transform
的一个功能——提前退出。使用 reduced
使这成为可能,但我也很少使用它。
但是提供给它的函数的全部要点(lodash 术语中的 iteratee
)是改变累加器对象。它的 return 将被忽略,除非您通过 returning false
发送 end the madness
信号。只有它的副作用才是真正重要的。
Ramda 是围绕避免突变而设计的。当你使用 Ramda 的 reduce
折叠到一个列表时,强烈的期望是你会使用 concat
而不是 push
;换句话说,您不会改变输入。 Ramda 没有强制执行这一点,有时出于性能原因回避这种期望,但是你可能必须小心在调用之间共享累加器。但 Ramda 肯定不会让它变得更容易。任何旨在仅用于其副作用的函数都是 Ramda 的诅咒。 (请不要提醒我forEach
!"A foolish consistency is the hobgoblin of little minds.")
请注意,customcommander 的回答并未尝试改变 acc
值,而是 return 编辑了一个新值:这是非常惯用的 Ramda。
另外一个非常不同的是 lodash 愿意在没有提供初始累加器的情况下创建一个初始累加器。 Ramda 不允许任何可选参数。它们只是不同的设计。
重要的一点是,没有特别的理由期望每个 lodash 函数都有一个 Ramda 等价物。 Ramda 是独立开发的,针对不同的编码风格,受制于不同的约束,并且从未设计为直接替代品。所以它与 lodash 的关系与 lodash 与 Underscore 的关系非常不同。
它们的重叠程度与它们的重叠程度一样多,这证明了两者都支持的许多功能的基本性质。当然,还有一个不可忽视的反馈循环,即人们从一个图书馆请求另一个图书馆的功能;但我认为很多功能只是被广泛需要更为重要。