admin 管理员组

文章数量: 1086019

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]

本文标签: javascriptFilter with multiple predicates elegant functional approachStack Overflow