对于数据列表,我想使用多个谓词对其进行过滤,然后对每个过滤器执行操作。
例如。如果我的数据是:
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 库)的最佳方法。纯函数式语言是如何完成的?
注意:
- 在这种情况下,数组顺序并不重要。
- 请不要按字面意思理解示例并建议替代解决方案,我想要一个通用解决方案来过滤和映射多个谓词的列表。
最佳答案
尝试这样:
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/