7
$\begingroup$

Suppose I want all two digit primes between -75 and 100 inclusive.

a=Range[-75,100]

Select[Select[Cases[a, ?_Positive],(#>9&)],PrimeQ] 

does it, but can't be the simplest way.

Cases[ a, _?Positive] and Cases[a, _?PrimeQ] 

individually work but

Cases[a, _? Positive && PrimeQ] 

fails, as do most of the variants I could think of using parenthesis and _? in from of both Positive and PrimeQ

Is there an elegant expression and is it possible to use logical operators with Cases in the way I am attempting?

$\endgroup$
  • 4
    $\begingroup$ Select[Range[-75, 100], (Positive[#] && PrimeQ[#] &)] $\endgroup$ – andre314 Mar 18 '17 at 13:03
  • $\begingroup$ Select[] is really much more preferable to Cases[] in this case. $\endgroup$ – J. M. is away Mar 18 '17 at 17:05
13
$\begingroup$

Generally I would use Condition:

Cases[Range[-75, 100], x_ /; Positive[x] && PrimeQ[x]]

For the specific case of And you can string PatternTest if you control grouping:

Cases[Range[-75, 100], (_?Positive)?PrimeQ]
{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47,
 53, 59, 61, 67, 71, 73, 79, 83, 89, 97}
$\endgroup$
  • 1
    $\begingroup$ +1 for (_?Positive)?PrimeQ. $\endgroup$ – Alexey Popkov Mar 23 '17 at 8:46
  • $\begingroup$ @Mr.Wizard +1 for showing me the use of a double pattern test $\endgroup$ – Ali Hashmi Mar 23 '17 at 9:28
  • $\begingroup$ I hope I don't anger my initial responder whose answer was excellent,but Mr Wizard's response has, in my view, the elegant edge so I switched the green check! $\endgroup$ – CMoller Mar 24 '17 at 12:06
  • $\begingroup$ @CMoller the short answer is: no you have not offended me because I am not here only for points. I consider Mr.Wizard as someone who I am learning from, I would suggest you to wait before making an accept. While I may not be here for points but removing accept does damage of points to the other person and shows up on their profile. You may offend someone else. $\endgroup$ – Ali Hashmi Mar 24 '17 at 19:58
  • 1
    $\begingroup$ @CMoller For my part I do not mind losing the check-mark to a better answer posted later. To discourage that would be to discourage posting of better answers after an Accept has been given, and that would work against everyone's best interest. Just be sure you don't "move the goalposts" after asking your question; if you receive (and perhaps accept) an answer to the question you asked, but then realize you want something different or more, post a new question. $\endgroup$ – Mr.Wizard Mar 24 '17 at 21:37
11
$\begingroup$
Cases[Range[-75, 100], _?(Positive[#] && PrimeQ[#] &)]

(* or *)

Cases[Range[-75, 100], _?(Apply[And, Composition[Positive[#], PrimeQ[#]]] &)]
(* which is the same as the one below*)

Cases[Range[-75, 100], _?(Apply[And, Positive[#1]@*PrimeQ[#1]] &)]

(* or even more compactly *)
Cases[Range[-75, 100], _?(And @@ Positive[#1]@*PrimeQ[#1] &)]

a different way with Cases:

(Cases[#, _?Positive] ⋂ Cases[#, _?PrimeQ]) &@Range[-75, 100]
$\endgroup$
  • $\begingroup$ @CMoller you are very welcome ! $\endgroup$ – Ali Hashmi Mar 18 '17 at 15:04
  • 1
    $\begingroup$ @AliHashmi Since you have expressed interest in my coding style you may wish to see my answer below. $\endgroup$ – Mr.Wizard Mar 23 '17 at 5:06
  • $\begingroup$ @Mr.Wizard I particularly enjoy your succinct way of coding style. Brief terse and enjoyable to read. I am trying to adopt a coding style which is a hybrid of yours and Leonid. I want to be able to switch to granularity when the need arises however being terse most of the times. $\endgroup$ – Ali Hashmi Mar 23 '17 at 20:33
3
$\begingroup$

You can use operator forms with Select:

Select[
    Range[-75,100],
    Through @* And[Positive, PrimeQ]
]

{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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