javascript - 在Underscore/Ramda/函数式语言/库中组合多个filter()谓词

标签 javascript dictionary filter functional-programming underscore.js

对于数据列表,我想使用多个谓词对其进行过滤,然后对每个过滤器执行操作。

例如。如果我的数据是:

var people = [
    {name: 'Sachin',    profession: 'doctor',   cases: 12},
    {name: 'Djokovic',  profession: 'lawyer',   cases: 14},
    {name: 'Paes',      profession: 'doctor',   cases: 36},
    {name: 'Jordan',    profession: 'lawyer',   cases: 78},
    {name: 'Williams',  profession: 'doctor',   cases: 30},
    {name: 'Nehwal',    profession: 'lawyer',   cases: 75}
]

我想将其转换为:

var peopleWithoutCases = [
    {name: 'Sachin',    profession: 'doctor',   patients:   12, cases: 12},
    {name: 'Djokovic',  profession: 'lawyer',   courtcases: 14, cases: 14},
    {name: 'Paes',      profession: 'doctor',   patients:   36, cases: 36},
    {name: 'Jordan',    profession: 'lawyer',   courtcases: 78, cases: 78},
    {name: 'Williams',  profession: 'doctor',   patients:   30, cases: 30},
    {name: 'Nehwal',    profession: 'lawyer',   courtcases: 75, cases: 75}
]

有没有像这样优雅的函数方法?

    people
    .filter (person => person.profession == 'doctor')
    .map    (person => {
                person.patients = person.cases
                return person;
            })
    .filter (person => person.profession == 'lawyer')
    .map    (person => {
                person.courtcases = person.cases
                return person;
            })

问题是第一个 map 返回一个只有 doctor 的数组。因此第二个过滤器返回[]

我知道我能做到:

_.union(
    people
        .filter (person => person.profession == 'doctor')
        .map    (person => {
                    person.patients = person.cases
                    return person;
                }),
    people
        .filter (person => person.profession == 'lawyer')
        .map    (person => {
                    person.courtcases = person.cases
                    return person;
                })
)

如果我错了,请纠正我,但是,这需要采用多遍方法来解决问题,在我看来,这种方法效率低下数组列表增长,谓词数量增长。

使用命令式方法编写此代码非常容易。具有多个 if 语句的单个 for 循环。高效但不优雅:)

请建议使用功能性 javascript(如 Underscore、LoDash 或 Excellent RamdaJS 库)的最佳方法。纯函数式语言是如何完成的?

注意:

  1. 在这种情况下,数组顺序并不重要。
  2. 请不要按字面意思理解示例并建议替代解决方案,我想要一个通用解决方案来过滤和映射多个谓词的列表。

最佳答案

尝试这样:

var el = document.getElementById('dbg');
var $l = function( val ){
  el.innerHTML = el.innerHTML + '<div class="line"><pre>' + val + '</pre></div>';
}



var people = [
    {name: 'Sachin',    profession: 'doctor',   cases: 12},
    {name: 'Djokovic',  profession: 'lawyer',   cases: 14},
    {name: 'Paes',      profession: 'doctor',   cases: 36},
    {name: 'Jordan',    profession: 'lawyer',   cases: 78},
    {name: 'Williams',  profession: 'doctor',   cases: 30},
    {name: 'Nehwal',    profession: 'lawyer',   cases: 75},
    {name: 'Nawak',     profession: 'developper',   cases: 750}
]

var modifiers = {
  'doctor' : function(  ){ this.patients =this.cases ; return this} , 
  'lawyer' : function(  ){ this.courtcases = this.cases; return this; } , 
  'developper' : function(  ){ this.program = this.cases; return this; } , 
}
var result = people.map(function( p){
      modifiers[p.profession].call( p );
      return p;
    })
console.dir(result);
$l( JSON.stringify( result , null , ' ' ) );
.line {
  border : solid 1px #AAA;
  padding : 3px;
  margin : 3px;
  }
<div id='dbg'></div>

关于javascript - 在Underscore/Ramda/函数式语言/库中组合多个filter()谓词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33014375/

相关文章:

python - python中的 "for key in dict"是否总是以固定顺序迭代?

javascript - 如何迭代这些参数来过滤数组?

css - 如何将 CSS 过滤器饱和应用于 SVG 元素?

javascript - NodeJS 和 Express - 导出函数跳过 SQLite3 DB 查询

javascript - 在 JavaScript 中格式化

ios - 如何快速从一系列键值对(元组)创建两个字符串数组

python - 将多个过滤器应用于元组列表

javascript - DOMContentLoaded 触发后是否应用样式?

javascript - Node.js:计算文件中的行数

Python 3.6 合并字典失败