2016-03-11 79 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