为什么我的 Ramda 管道功能不能与过滤器一起使用?

Ami*_*ole 1 javascript functional-programming pipe filter ramda.js

我有一个柯里化函数,我在组合中使用它,它有效:

const getClubs = R.filter(R.propEq('suit', 'CLUBS'))
Run Code Online (Sandbox Code Playgroud)

这是接收一系列纸牌对象并按它们的花色过滤它们。

但是当我尝试取消嵌套这个函数调用并将其变成管道时:

const getClubs = R.pipe(R.filter, R.propEq('suit', 'CLUBS'))
Run Code Online (Sandbox Code Playgroud)

...这不再起作用,我什至没有收到任何错误。我的管道或过滤器功能做错了什么?

这是我的代码的工作版本

在第 8 行和第 9 行之间切换以查看我上面描述的问题

Sco*_*yet 5

这至少有两个问题。首先,你很困惑compose并且pipe。它们非常相似,但它们以相反的顺序应用其功能。

pipe(g, f)(x);    //=> f(g(x))

compose(g, f)(x); //=> g(f(x))
Run Code Online (Sandbox Code Playgroud)

因此,如果您想要等效的filter(propEq('suit', 'CLUBS')),那么您需要编写以下内容之一来代替R.pipe(R.filter, R.propEq('suit', 'CLUBS'))

R.pipe(R.propEq('suit', 'CLUBS'), R.filter)
// or
R.compose(R.filter, R.propEq('suit', 'CLUBS'))
Run Code Online (Sandbox Code Playgroud)

但第二个问题更为根本。 pipe并且compose不要将其功能列表中的一项传递给另一项。相反,它们返回的函数中,第一个函数根据提供的数据调用,第二个函数根据第一个函数的结果调用,第三个函数根据第二个函数的结果调用,第四个函数根据第三个函数的结果调用,等等。

filter需要两个参数,一个谓词函数和一个值列表。

由于柯里化,您filter(propEq('suit', 'CLUBS'))正在传递filter(propEq('suit', 'CLUBS'))一个只有一个参数的函数 to filter,它需要一个单参数函数和一个值列表。因为我们只传递了第一个,所以我们返回一个函数,该函数接受值列表并将其过滤到匹配的值。

当您尝试使用pipe(propEq('suit', 'CLUBS'), filter)名为 的列表调用结果函数时cards,您将传递cardspropEq('suit', 'CARDS'),并且由于cards是一个没有属性的列表suit,因此它返回 false。然后您可以filter使用该false值进行调用。由于此柯里化函数需要两个参数,因此您将返回一个寻找第二个参数的函数。但它是一个无用的函数,因为第一个参数false不是谓词函数。

我希望这是有道理的。昨晚我没睡好,我不太确定什么是明智的。:-)

  • 我 *sooo* 希望其他图书馆作者能像你一样活跃在 SO 上...... (2认同)
  • @AmitErandole:您正在寻求解决方案,但我不知道问题是什么。我认为 `R.filter(R.propEq('suit', 'CLUBS'))` 绝对没有任何问题。为什么要改变它?在我看来,它与“map(add(5))”没有什么不同。您只需将部分配置的函数传递给另一个函数即可。这感觉很自然。 (2认同)