gpt4 book ai didi

javascript - 通过 ramda.js 使用高阶函数进行映射

转载 作者:行者123 更新时间:2023-11-28 04:17:05 24 4
gpt4 key购买 nike

我的代码中有一个不断重复出现的模式,看起来它应该很常见,但我一生都无法弄清楚它叫什么或者是否有常见的处理方法:map使用接受参数的函数,该参数本身就是接受 map 的函数的结果ed 元素作为参数。

这是模式本身。我已将我想要的函数命名为 mapply ( map 应用),但这似乎是错误的名称:

const mapply = (outer, inner) => el => outer(inner(el))(el)

这实际上叫什么?我怎样才能用惯用的 Ramda 来实现它?看来这世界上一定有聪明人告诉我如何处理它。

我的用例是做一些基本的准牛顿物理工作,向物体施加力。要计算一些力,您需要一些有关物体的信息 - 位置、质量、速度等。一个(非常)简化的示例:

const g = Vector.create(0, 1),
gravity = ({ mass }) => Vector.multiply(mass)(g),
applyForce = force => body => {
const { mass } = body,
acceleration = Vector.divide(mass)(force)

return R.merge(body, { acceleration })
}

//...

const gravitated = R.map(mapply(applyForce, gravity))(bodies)

谁能告诉我:这是什么?你会如何Ramda-fy它?我应该注意哪些陷阱、边缘情况和困难?有哪些明智的处理方法?

(我搜索了又搜索——所以,Ramda 的 GitHub 存储库,以及其他一些函数式编程资源。但也许我的 Google-fu 没有达到它需要的位置。如果我忽略了一些明显的东西,我很抱歉。谢谢!)

最佳答案

这是一篇作文。它具体是compose(或者pipe,如果你想倒退的话)。

在数学中(例如,单变量微积分),您可能会有一些诸如 fxf(x) 之类的语句,表示存在某个函数 f,它变换 x,并且变换应在别处描述......

当你看到(g º f)(x)时,你就会陷入疯狂。 “G of F”(或许多其他描述)。

(g º f)(x) == g(f(x))

看起来很眼熟吗?

const compose = (g, f) => x => g(f(x));

当然,您可以通过使用组合函数作为组合函数内部的操作来扩展此范例。

const tripleAddOneAndHalve = compose(halve, compose(add1, triple));
tripleAddOneAndHalve(3); // 5

对于此版本的可变参数,您可以执行以下两种操作之一,具体取决于您是想更深入地了解函数组合,还是想稍微理顺一下。

// easier for most people to follow
const compose = (...fs) => x =>
fs.reduceRight((x, f) => f(x), x);

// bakes many a noodle
const compose = (...fs) => x =>
fs.reduceRight((f, g) => x => g(f(x)));

但是现在,如果您采用柯里化(Currying)或部分map之类的东西,例如:

const curry = (f, ...initialArgs) => (...additionalArgs) => {
const arity = f.length;
const args = [...initialArgs, ...additionalArgs];
return args.length >= arity ? f(...args) : curry(f, ...args);
};

const map = curry((transform, functor) =>
functor.map(transform));

const reduce = ((reducer, seed, reducible) =>
reducible.reduce(reducer, seed));

const concat = (a, b) => a.concat(b);

const flatMap = curry((transform, arr) =>
arr.map(transform).reduce(concat, []));

你可以做一些漂亮的事情:

const calculateCombinedAge = compose(
reduce((total, age) => total + age, 0),
map(employee => employee.age),
flatMap(team => team.members));

const totalAge = calculateCombinedAge([{
teamName: "A",
members: [{ name: "Bob", age: 32 }, { name: "Sally", age: 20 }],
}, {
teamName: "B",
members: [{ name: "Doug", age: 35 }, { name: "Hannah", age: 41 }],
}]); // 128

非常强大的东西。当然,所有这些都可以在 Ramda 中实现。

关于javascript - 通过 ramda.js 使用高阶函数进行映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45741071/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com