Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

If I have an array that looks like this:

testArray = 
  {{"StringOne", 3.444}, {"StringOne", 433}, {"StringOne", 1}, {"StringOne", 8}, 
   {"StringOne", 1}, {"StringOne", 5}, {"StringOne", 2}, {"StringOne", 1}, 
   {"StringOne", 9}, {"StringOne", 1}, {"StringTwo", 7.64}, {"StringTwo", 34}, 
   {"StringTwo", 6}, {"StringTwo", 99}, {"StringTwo", 54}, {"StringTwo", 12.33}, 
   {"StringTwo", 6}, {"StringTwo", 7}, {"StringTwo", 76}, {"StringTwo", 1}};

I want to quickly detect the existence of a subarray of the form: {"StringTwo", n} for all $n > k$ (for some real-valued $n$ and $k$).

How can I best do this?

share|improve this question
    
Select & Cases –  Sektor Jan 4 at 14:23
1  
Cases[testArray, {_, x_} /; x > 75] –  bobthechemist Jan 4 at 15:22

3 Answers 3

up vote 2 down vote accepted

You can use

Position[testArray, "StringTwo"]
{{11, 1}, {12, 1}, {13, 1}, {14, 1}, {15, 1}, {16, 1}, {17, 1}, 
 {18, 1}, {19, 1}, {20, 1}}

or can test for the presence of an element using

MemberQ[testArray, "StringTwo", 2]
True

Adding in the extra parameter $k$, we can test whether any of the second elements are larger than $k$ using:

Length[Select[
   First@Rest@
     Transpose[
      testArray[[First@
         Transpose@Position[testArray, "StringTwo"]]]], # > k &]] > 0

Replace k by 9 and you get True. Replace k by 100 and you get False as expected. Of course you would probably want to make this into a function for easy use. Somewhat more concisely, you could use:

Select[testArray, (#[[1]] == "StringTwo") && (#[[2]] > 9) &] != {}

which directly checks if there are any elements of testArray with first element equal to "stringTwo" and second element that is > k.

share|improve this answer
    
I'm just trying to quickly determine if there exists some element in that larger array of the form: {"StringTwo",n} where "n" is some integer or real number > k (an arbitrarily specifiable threshold). –  user11565 Jan 4 at 13:21
    
I'm just looking for a way to ask if an element like this (i.e. a subarray like this) exists in testArray, with a TRUE or FALSE result. I need to do this efficiently. –  user11565 Jan 4 at 13:22
    
Then you don't really mean "for all n", you mean "for some n", since it will never be true that an element exists for all n. –  bill s Jan 4 at 13:27
    
I meant "for all n > k" in the question description, but you're right, I wasn't clear. –  user11565 Jan 4 at 13:38

Try

k = 10; 
Cases[testArray, {"StringTwo", n_} /; n > k, 1, 1] != {}

(* True *)

Since you are only testing for existence you want to use a method that short-cuts, that is, returns True as soon as it finds any instance of what you are looking for. The third and fourth argument of Cases specify to only search the 1st level of the list and return the first instance it finds. The search pattern is written to find a list with a literal "StringTwo" followed by a pattern n subject to the constraint that n>k. Here is a tutorial on the use of constraints with patterns.

share|improve this answer

For True or False result Catch and Throw is a good option, because it breaks the evaluation when the condition match. Here is:

memberQ[list_List,string_String,value_?NumberQ]:=
   Catch[If[#[[1]]==string&&#[[2]]>value,Throw[#]]&~Scan~list]=!=Null

Let's test it

memberQ[testArray,"StringTwo",5]

True

Time Performance

bigTestArray=Join @@ Table[testArray, {i, 1, 100000}]

MemberQ[bigTestArray, {"StringTwo", x_} /; x > 5] // AbsoluteTiming
memberQ[bigTestArray,"StringTwo",5]//AbsoluteTiming
Cases[bigTestArray, {"StringTwo", n_} /; n > 5, 1, 1] != {}//AbsoluteTiming
Select[bigTestArray, (#[[1]] == "StringTwo") && (#[[2]] > 5) &] != {} // AbsoluteTiming
{0.000036,True}
{0.000081,True}
{0.017640,True}
{3.542719,True}
share|improve this answer
    
For me, MemberQ[bigTestArray, {"StringTwo", x_} /; x > 5] // AbsoluteTiming is twice as fast as memberQ. –  Pickett Jan 5 at 1:42
    
tks @Anon, answer improved. –  Murta Jan 5 at 13:24

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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