# How to combine multiple pure conditions with an AND operator?

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?

• Welcome to the Mathematica Stack Exchange. Please search the docs for And.
– Syed
Apr 17 at 16:00

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.