【问题标题】:generic filtering of JSON objects in js using Ramda使用 Ramda 对 js 中的 JSON 对象进行通用过滤
【发布时间】:2015-06-19 07:08:51
【问题描述】:

我希望实现尽可能通用和功能性(如在函数式编程中),但一般来说,我希望 json 具有以下结构:

[
 {
   id: number,
   prop1: string,
   prop2: number,
   prop3: string,
   ...,
   propN: string
 },
 ...
]

(基本上是一个包含 N 个属性的对象数组,其中一些映射到字符串,另一些映射到数字)

我正在尝试实现一组通用功能,以便我能够为此实现一些目标:

var filteredResult = filter(by(property, value, lt\gt\eq\contains), collection);

基本上,我想返回一个具有相同对象结构的数组,由我传递给 by() 的属性字符串过滤,以及值(字符串或数字)和比较类型 i想要表演。

一般来说,对于数字,我希望能够过滤属性值大于/小于/在我传递的值范围内的结果,使用字符串或字符串数​​组,我想找出如果属性值包含我传入 by() 的值。

由于我是 FP 的新手,我正在努力格式化我的代码以利用 Ramda 提供的自动柯里化功能,并且在传递我想要的参数时组合不同的函数时遇到了麻烦。

比如我写了这个函数:

var byProperty = function(p) {return R.useWith(R.filter, R.propEq(p), R.identity)};

但是当我尝试这样使用它时:

var property = 'prop1', value = 15;
console.log( byProperty( property, value, collection ) );

我得到一个函数而不是过滤后的数组。

我知道我在这里遗漏了一些琐碎的事情,但是我很难理解在 Ramda 中传递值和函数的方式。

【问题讨论】:

    标签: javascript json functional-programming filtering ramda.js


    【解决方案1】:

    但是当我尝试像console.log( byProperty( property, value, collection ) ) 一样使用它时,我得到了一个函数而不是过滤后的数组。

    是的,因为您的函数只接受一个参数,并返回一个函数。你可以这样调用它:

    console.log( byProperty(property)(value, collection) );
    

    但这可能不是你想要的。另外,我认为useWith 在这里是错误的工具,您只需要compose

    var byProperty = R.compose(R.filter, R.propEq);
    

    虽然这仍然需要像这样调用

    console.log( byProperty(property, value)(collection) );
    

    对此有an open issue,但柯里化和组合可变参数函数并非易事。你会得到最好的可能是

    var byProperty = R.curryN(3, function(p, v, c) { return R.filter(R.propEq(p, v), c); });
    

    【讨论】:

    • 谢谢!这为我清除了很多东西。在您的最后一个示例中,是否可以将函数引用作为参数传递,而不是硬编码的 R.propEq?
    • @airbag:是的,你可以。只需确保 filter 被调用时使用它所期望的 - 谓词。
    猜你喜欢
    • 2019-06-05
    • 2015-10-20
    • 1970-01-01
    • 1970-01-01
    • 2014-02-19
    • 1970-01-01
    • 2020-06-28
    • 1970-01-01
    • 2017-09-06
    相关资源
    最近更新 更多