Ramda中与Lodash _.transform等价的函数是什么?
嘿,我正好研究过这个问题!Ramda确实没有直接和Lodash _.transform 完全等价的内置函数,但我们可以用Ramda的现有工具自己实现一个,还能贴合它的函数式风格。
用Ramda复刻Lodash _.transform的功能
先拆解下你给出的Lodash示例逻辑:
_.transform([2, 3, 4], function(result, n) { result.push(n *= n); return n % 2 == 0; }, []); // => [4, 9]
这段代码是遍历数组元素,把每个元素平方后塞进结果数组,当平方后的数是偶数时继续遍历,遇到奇数就立刻停止(注意:_.transform里迭代器返回true表示继续,false终止)。
Ramda里的R.reduceWhile正好是做「带终止条件的归约」的工具,我们可以用它来实现等价功能:
方式1:复刻Lodash的可变累加器行为
如果你习惯Lodash那种直接修改累加器的写法,可以这样实现:
const transform = (fn, initialAcc, collection) => R.reduceWhile( // 终止判断:迭代器返回false时停止遍历 (acc, val) => fn(acc, val), // 归约逻辑:调用迭代器后返回原累加器(因为迭代器已经修改了它) (acc, val) => { fn(acc, val); return acc; }, initialAcc, collection ); // 测试你的示例 transform( (result, n) => { result.push(n *= n); return n % 2 === 0; }, [], [2, 3, 4] ); // => [4, 9]
方式2:贴合Ramda的纯函数风格
如果想遵循Ramda的无副作用原则,我们可以调整逻辑,让迭代器返回「是否继续遍历」和「新的累加器」的组合,避免直接修改原数组:
const pureTransform = (fn, initialAcc, collection) => R.reduceWhile( // 从迭代器返回值里取是否继续的标识 ([shouldContinue]) => shouldContinue, // 调用迭代器,拿到新的状态 ([_, acc], val) => fn(acc, val), // 初始状态:[是否继续, 初始累加器] [true, initialAcc], collection )[1]; // 最后取出最终的累加器 // 纯函数版本的示例调用 pureTransform( (result, n) => { const squared = n * n; const newResult = [...result, squared]; // 返回[是否继续遍历, 新的结果数组] return [squared % 2 === 0, newResult]; }, [], [2, 3, 4] ); // => [4, 9]
两种方式都能实现你要的效果,前者完全对齐Lodash的使用习惯,后者更符合Ramda的函数式编程理念。
内容的提问来源于stack exchange,提问作者polonio
相关产品推荐
相关产品推荐

