I have a list of Pure conditions {con1[#]&,con2[#]&,con3[#]&} and want to combine them in one Pure Function con1[#] && con2[#] && con3[#] & to use it in a Select[data,test] expression.
How can I do that?
step by step
finally we need
con1[x] && con2[x] && con3[x] which is
AllTrue[{con1[x], con2[x], con3[x]} , #&] or And @@ {con1[x], con2[x], con3[x]} to get {con1[x], con2[x], con3[x]}, we need Through
Through[{con1, con2, con3}[x]] put together
Through[{con1, con2, con3}[x]] // Apply[And] rewrite it as a function
test = Function[{x}, Through[{con1, con2, con3}[x]] // Apply[And]] You basically had it. I think you might just be getting thrown by the shorthand notations & and &&. So, you could just use the normal prefix form of And. For example,
Select[Range[20], And[Divisible[#, 3], Divisible[#, 2]] &] (* {6, 12, 18} *) If you really want postfix/infix forms...
Select[Range[20], Divisible[#, 3] && Divisible[#, 2] &] (* {6, 12, 18} *) The && binds "tighter" than &, so this just works without parentheses, but there are cases where you need to be aware of precedence and use parentheses.
Using ComapApply (new in 14.0)
And @@ ComapApply[{con1, con2, con3},{x}] con1[x] && con2[x] && con3[x]
We could define an operator combine that transforms a list of functions into another function that tests if all the originals return true when applied to an argument.
If we know for certain that all of the initial functions are pure slot-based functions (as in the question), we can define the operator using Distribute:
combine[constraints:{Function[_]..}] := Distribute[And @@ constraints, Function, And] So then:
Select[{10, 21, 30, 41}, combine[{# > 15 &, # < 35 &}]] (* {21, 30} *) combine[{con1[#] &, con2[#] &, con3[#] &}] (* con1[#1] && con2[#1] && con3[#1] & *) Note that the operator is explicitly defined to operate only upon lists of pure slot-based functions. If it is desirable to support any kinds of functions, then we could use this more elaborate form:
combine[constraints_List] := AllTrue[constraints, OperatorApplied[Construct][#]]& So then:
Select[{10, 21, 30, 41}, combine[{GreaterThan[15], OddQ, #<35&}]] (* {21} *) combine[{f, g, h}] (* AllTrue[{f, g, h}, OperatorApplied[Construct][#1]] & *) Both of these definitions have the feature that they will stop evaluating functions as soon as the first returns false. That is, unneeded function evaluations are avoided.
And. $\endgroup$