Ramda 使用 gte 条件过滤数据

Ramda filter data with gte condition

我有 JSON 数据

 {
   "date": "2019-12-17",
   "installs": 1,
 },
 {
   "date": "2019-12-02",
   "installs": 5
 },
 {
   "date": "2019-12-02",
   "installs": 4
 }
 ....

我需要在一个字段(例如安装)上按 gte 条件过滤它

我试过这个代码:

    let f = R.filter(R.propIs(true, R.gte(R.prop('installs'), 2)), data);
    console.log(f)

但出现错误

TypeError: Right-hand side of 'instanceof' is not an object

我认为您的尝试对如何使用 Ramda 的功能组合思想有些困惑。可能最接近您的工作版本如下所示:

filter(pipe (prop ('installs'), gte (__, 2), equals (true)), data)

我将提取并命名传递给 filter 的函数以供我们讨论。如果你没有别的用处,当然可以稍后再内联。

const enoughInstalls = pipe (prop ('installs'), gte (__, 2), equals (true))
filter (enoughInstalls) (data)

请注意,当我们想要创建一个将数据从一个函数传递到另一个函数的函数时,我们不会将它们嵌套在 gte(prop('installs'), 2) 之类的东西中。因为 prop('installs') 是一个 函数 ,这需要将 函数 作为第一个参数传递给 gte。当然,您需要传递一个数字。当我们想将一个函数调用的结果传递给另一个时,我们使用函数组合,通常使用Ramda的compose or its pipe。我们将在这里做后者,但 compose 非常相似,只是参数颠倒了。

所以我们使用 pipe(prop('installs'), gte(__, 2)) 而不是 gte(prop('installs'), 2)。 return 是一个函数,它将其参数传递给 prop('installs') 并将该调用的结果传递给 gte(__, 2)。上面还有一个管道中的调用,equals(true)。这是在尝试匹配您的 propIs 想法。但事实证明这是完全没有必要的。 gte 将 return 一个布尔值。因此,将 equals(true) 添加到 return 是相同的布尔值。所以这可以简化为:

const enoughInstalls = pipe (prop ('installs'), gte (__, 2))

这表示从我们的输入对象中获取 属性 installs 并将其传递给谓词函数 gte(__, 2)。但是有一个内置函数 propSatisfies。我们可以将其重写为:

const enoughInstalls = propSatisfies (gte (__, 2), 'installs')

这是一个非常合理的解决方案。但我实际上更喜欢 Nick Parsons 在评论中建议的版本。对于这个,我真的更喜欢在 filter 调用中内联:

const myFilter = filter (where ({installs: gte(__, 2)})

大声朗读为“安装量大于或等于 2 的过滤器”,这几乎可以想象到可读性。