最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Filter with multiple predicates, elegant functional approach - Stack Overflow

programmeradmin2浏览0评论

I'm trying to implement filtration logic in my app. There's a table and every column header contains an input field and dropdown with filter options, you can set a filter by selecting an option e.g. "equal to", "not equal to", "starts with", "contains", "does not contain", "ends with", etc. (options would change for different types of data). Something similar to KendoUI grid

Now what I can't get my head around is how to create a function that would filter data array by using predicates of selected filters (it is possible to set multiple filters)

I just started using ramda.js and I think that project is really awesome. I guess I could use either that or lodash/underscore (I prefer ramda though)

If anyone can show me a snippet, something to start with - I'll be very grateful

I'm trying to implement filtration logic in my app. There's a table and every column header contains an input field and dropdown with filter options, you can set a filter by selecting an option e.g. "equal to", "not equal to", "starts with", "contains", "does not contain", "ends with", etc. (options would change for different types of data). Something similar to KendoUI grid

Now what I can't get my head around is how to create a function that would filter data array by using predicates of selected filters (it is possible to set multiple filters)

I just started using ramda.js and I think that project is really awesome. I guess I could use either that or lodash/underscore (I prefer ramda though)

If anyone can show me a snippet, something to start with - I'll be very grateful

Share Improve this question edited Sep 26, 2014 at 6:31 iLemming asked Sep 25, 2014 at 23:28 iLemmingiLemming 36.3k61 gold badges198 silver badges316 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 7

I think you're looking for the R.allPass function. You'd simply do

var selectedPredicates = …;
R.filter(R.allPass(selectedPredicates))(list)

I'm not entirely clear if you mean what I think you do, so here are my assumptions:

  • You have a list of predicates over some type t, that is, something of type [t -> Bool],
  • and you want to get out of that one predicate, which is true iff the conjunction of all the predicates in the list holds of its input.

Then you could use a fold with a lifted conjunction operator and a constantly true base case (with an empty list, "all" predicates trivially hold). This Haskell code works:

> let f = foldr (\f g -> \x -> f x && g x) (const True) [(>2), (<=10)]
> f 5
True
> f 1
False

Using JS and ramda, f would probably look somehow like this (untested):

var f = R.reduce(function(f, g) { 
                   return function(x) { return f(x) && g(x); };
                 },
                 alwaysTrue,
                 your_actual_predicates);

const moreThan2 = n => n > 2;
const lessThan5 = n => n < 5;

const filtered = [1, 2, 3, 4, 5]
  .filter(n => [moreThan2, lessThan5].every(pred => pred(n)));

console.log(filtered); // [3,4]

发布评论

评论列表(0)

  1. 暂无评论