2
$\begingroup$

I read the doc about Position built-in function:

"Position[expr, pattern] gives a list of the positions at which objects matching pattern appear in expr."

For instance:

Position[{"a", "b", "A", "a", "B", "c", "b"}, "b"]

returns

{{2}, {7}}

However, I am desperately looking for a built-in function that works with a test instead of a pattern matching. To be clear I would like a built-in function that behaves as follow:

(* does not work, for illustration purpose *)
Position[{"a", "b", "A", "a", "B", "c", "b"},UpperCaseQ] 

would return:

{{3}, {5}}

I am aware of the Select function,

Select[{"a", "b", "A", "a", "B", "c", "b"}, UpperCaseQ]

but it returns values and not positions (and I want positions!):

{"A", "B"}

Question: Do I miss read the doc, maybe such built-in function exist?

$\endgroup$
0

3 Answers 3

4
$\begingroup$
Position[UpperCaseQ /@ vars, True]
$\endgroup$
6
$\begingroup$

I just found this:

Position[{"a", "b", "A", "a", "B", "c", "b"}, _String?UpperCaseQ]

is working.


Update: Albert Retey, just rightly commented that it works without the head check.

For instance:

Position[Range[10], _?OddQ]

is working.

$\endgroup$
4
  • 1
    $\begingroup$ that's something along the lines of what I was going to suggest. :) $\endgroup$
    – rcollyer
    Commented Nov 20, 2017 at 16:33
  • $\begingroup$ @rcollyer, thanks. On my side it was not on purpose. I was annoyed by this and just found the solution I posted. $\endgroup$ Commented Nov 20, 2017 at 16:37
  • 1
    $\begingroup$ this would work equally well without the head-check, e.g.: Position[{0.,-1,5,-5.3},_?Negative]. That is probably just relevant for those cases where your entries do not all have the same head but I often use it without checking for the head, the typical test function would return false for non-matching entries anyway, cf.: OddQ["a"] $\endgroup$ Commented Nov 20, 2017 at 21:35
  • $\begingroup$ @AlbertRetey thanks for the constructive comment, I have updated my answer. $\endgroup$ Commented Nov 20, 2017 at 21:53
1
$\begingroup$

You could try something like this.

vars = {"a", "b", "A", "a", "B", "c", "b"};

Position[Table[UpperCaseQ[vars[[i]]], {i, Length[vars]}], True]

(*{{3},{5}}*)
$\endgroup$
9
  • $\begingroup$ Thanks, for your answer. I just found something that seems to work ( Position[{"a", "b", "A", "a", "B", "c", "b"}, _String?UpperCaseQ] ) $\endgroup$ Commented Nov 20, 2017 at 16:31
  • $\begingroup$ @Picaud Vincent Nice! $\endgroup$
    – Bob Brooks
    Commented Nov 20, 2017 at 16:33
  • $\begingroup$ Thanks, I only hope this can work in all cases, the syntax _String?UpperCaseQ is not the most natural one. $\endgroup$ Commented Nov 20, 2017 at 16:34
  • $\begingroup$ why? i find it elegant: it select all the string elements and test them with UpperCaseQ $\endgroup$
    – Alucard
    Commented Nov 20, 2017 at 16:37
  • 1
    $\begingroup$ @PicaudVincent try Position[Range[10], _Integer?OddQ] $\endgroup$
    – Alucard
    Commented Nov 20, 2017 at 16:43

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