4
$\begingroup$

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?

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

4 Answers 4

5
$\begingroup$

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]]
$\endgroup$
4
$\begingroup$

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.

$\endgroup$
3
$\begingroup$

Using ComapApply (new in 14.0)

And @@ ComapApply[{con1, con2, con3},{x}]

con1[x] && con2[x] && con3[x]

$\endgroup$
1
$\begingroup$

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.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.