2016-03-11 78 views
0

我正在掌握使用除简单的map或两个以外的函数编程。我有一种情况,我希望能够根据这些对象的特定字段筛选对象数组中的某些元素。这是一个人为的例子,但这里有:执行数组上的函数列表

我有一个字段定义的列表,我想根据他们的标题提取他们两个。

const toSearch = [ 
    { title: "name", description: "Their name" }, 
    { title: "age", description: "Their age" }, 
    { title: "gender", description: "Their gender" } 
] 

const fieldsToFind = ["name", "age"] 
let filterObjects = R.map(R.objOf('title'), fieldsToFind) 
let filterFuncs = R.map(R.whereEq(R.__), filterObjects) 
let found = R.map(R.filter, filterFuncs) 

console.log("Filter objects:", JSON.stringify(filterObjects)) 
console.log("Filter functions:", JSON.stringify(filterFuncs)) 

console.log("Found:", found[0](toSearch)) 
console.log("Found:", found[1](toSearch)) 

如果我运行这个,最后输出的是toSearch两个要素,我正在寻找,但它不是完全整齐。我一直试图让另一个map工作来手动执行found元素,但我也觉得,即使导致到那一点,我正在采取过于迂回的路线。

虽然这是一个人为的例子,是否有一个完美的方式来实现这一功能风格?

回答

2

一个相当简单的方法是:

R.filter(R.where({R.title: R.contains(R.__, ['name', 'age'])}))(toSearch); 
//=> [ 
//  {"description": "Their name", "title": "name"}, 
//  {"description": "Their age", "title": "age"} 
// ] 

,或者等价地,

R.filter(R.where({title: R.flip(R.contains)(['name', 'age'])}))(toSearch); 

一个优点,特别是如果您从导入相关功能到你的范围,是多么紧密这个读你的问题域:

var myFunc = filter(where({title: contains(__, ['name', 'age'])})); 

myFunc的=过滤器在标题中包含“名”或“年龄”。

你可以看到在行动本就Ramda REPL

+0

最后一个很棒!只是我正在寻找的那种整洁! – chooban

+0

是的,我真的很喜欢['where'](http://ramdajs.com/docs/#where)读取! –

0

您可以使用.reduce来完成您的任务。 MDN有降低作用

+0

但是如果我想要输入数组中的多个元素,我可以使用reduce吗?我想我可以使用一个数组作为累加器。 – chooban

+0

您可以使用任何类型的acc。只需提供一个空数组作为初始值 –

0

我有,我希望能够从对象的数组,过滤掉一些元素 ,基于这些 对象的特定领域的情况非常简短的解释。

对于您的情况,它很简单这样做的

var filteredItems = toSearch.filter(function(value){ return fieldsToFind.indexOf(value.title) != -1 }); 
+1

是的,这绝对是明智的选择。在某种程度上,我试图找到一个过于复杂的解决方案,只是为了了解一些链接功能。 – chooban