首页 > 解决方案 > 具有 gte 条件的 Ramda 过滤数据

问题描述

我有带有数据的 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

标签: javascriptconditional-statementsfilteringramda.js

解决方案


我认为你的尝试显示了一些关于如何使用 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. 当然,您需要传递一个数字。当我们想将一个函数调用的结果传递给另一个时,我们使用函数组合,通常使用 Ramdacompose或它的pipe. 我们将在这里做后者,但compose非常相似,只是参数颠倒了。

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

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

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

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

这是一个完全合理的解决方案。但我实际上更喜欢尼克帕森斯在评论中建议的版本。对于这个,我真的更喜欢在filter调用中内联:

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

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


推荐阅读