1
$\begingroup$

Is there a command working exactly like Matlab's find?

I know that Pick might work, but I just want to give a logic condition to select the elements of a list instead of a particular value.

For instance:

T={a, b, c, d, e}
Ctl={2.3, 0, 5, 0, 0}

I'd like to pick the elements of T for which the corresponding element of ctl is greater than 0.

$\endgroup$

closed as off-topic by MarcoB, user9660, Jens, dr.blochwave, LLlAMnYP Nov 9 '15 at 8:35

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "This question arises due to a simple mistake such as a trivial syntax error, incorrect capitalization, spelling mistake, or other typographical error and is unlikely to help any future visitors, or else it is easily found in the documentation." – MarcoB, Community, Jens, dr.blochwave, LLlAMnYP
If this question can be reworded to fit the rules in the help center, please edit the question.

  • 5
    $\begingroup$ Yes, Pick[] is entirely appropriate: Pick[T, Positive[Ctl]]. $\endgroup$ – J. M. will be back soon Nov 8 '15 at 17:08
  • $\begingroup$ Thanks! And if I wanted to to know the position of the element of Ctl >2? $\endgroup$ – pugliam Nov 8 '15 at 17:13
  • 1
    $\begingroup$ Replace T with Range[Length[T]], or something like that... $\endgroup$ – J. M. will be back soon Nov 8 '15 at 17:14
  • 4
    $\begingroup$ Now that I think about it, Position[] is useful, too: Position[Ctl, x_ /; x > 2]. $\endgroup$ – J. M. will be back soon Nov 8 '15 at 17:31
10
$\begingroup$

You can find the position/index within an array of all values in a specified interval, (like Matlab's find) using Position. For instance:

pos = Position[a, _?((0.3 < # < 0.7) &)]

or

pos = Position[a, x_ /; (0.3 < x < 0.7)]

These find the indices of all elements in a with values between 0.3 and 0.7. The elements can be extracted from a using

Extract[a, pos]

For the requested example:

t = {a, b, c, d, e};
ctl = {2.3, 0, 5, 0, 0};
pos = Position[ctl, _?((# > 2) &)]
Extract[t, pos]

{{1}, {3}}
{a, c}

As suggested by J.M. in the comments, you can also use Pick:

Pick[t, Thread[ctl > 2]]
{a, c}
$\endgroup$
4
$\begingroup$

You use a PositionIndex with KeySelect for this, which is a good approach if you need to use multiple tests against the same array.

In[1]:= T = {a, b, c, d, e}; 
        Ctl = {2.3, 0, 5, 0, 0};

In[2]:= index = PositionIndex[Ctl]
Out[2]= <|2.3 -> {1}, 0 -> {2, 4, 5}, 5 -> {3}|>

In[3]:= Extract[T, Values@KeySelect[index, Positive]]
Out[3]= {a, c}
$\endgroup$
  • $\begingroup$ Didn't know PositionIndex! $\endgroup$ – Silvia Nov 9 '15 at 2:35
  • $\begingroup$ @Pillsy thank you for introducing PositionIndex to me +1 :) $\endgroup$ – ubpdqn Nov 9 '15 at 8:33
1
$\begingroup$

Just for some ridiculousness (covering some of the give answers):

t = {a, b, c, d, e};
ctl = {2.3, 0, 5, 0, 0};

Various:

Pick[t, Positive@ctl] (* JM*)
Extract[t, Position[ctl, _?Positive]] (* bill s *)
Cases[Transpose[{t, ctl}], {x_, _?Positive} :> x]
First /@ Select[Transpose[{t, ctl}], #[[2]] > 0 &]
Last@Reap[Sow @@@ (Transpose@{t, ctl}), _?Positive, Sequence @@ #2 &]
True /. GroupBy[Transpose[{t, ctl}], Positive[#[[2]]] & -> First]
$\endgroup$

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