15
$\begingroup$

I am trying to get Position work with patterns. I have the following code:

dat = {"star", "u", "g", "r", "i", "z", "star2", "u", "g", "r", "i", 
   "z", "star3", "u", "g", "r", "i", "z", "star4", "u", "g", "r", "i",
    "z", "Astro", "u", "g", "r", "i", "z"};
Position[dat, "star" ~~ _]
Position[dat, RegularExpression["star."]]

Netheir returns anything. What I want is to return position of "star", "star2" etc. How do I properly use patterns with Position?

$\endgroup$
2
  • $\begingroup$ @kglr No, this does not return the first one. Also it returns empty fields of dimensions of the original list. I would prefer make it work in the way Position works and also understand why this does not actually work $\endgroup$
    – atapaka
    Commented Jun 13, 2016 at 22:01
  • 2
    $\begingroup$ As to the "why?"... Patterns and string patterns are two distinct syntactic forms. Position only supports the former. The reasons for the distinction are discussed in (8945). $\endgroup$
    – WReach
    Commented Jun 14, 2016 at 14:20

4 Answers 4

14
$\begingroup$
Position[dat, _String?(StringMatchQ[#, "star" ~~ ___] &)]

or

Position[dat, _String?(StringMatchQ[#, "star*"] &)]

or

Position[dat, _?(StringMatchQ[#, "star*"] &), Heads -> False]

or

Position[StringMatchQ[dat, "star*"], True] (*thanks: @TomD *)

{{1}, {7}, {13}, {19}}

Alternatively,

Pick[Range@Length@dat, StringMatchQ[#, "star*"] & /@ dat]

{1, 7, 13, 19}

$\endgroup$
2
  • 4
    $\begingroup$ Slight variant: Position[StringMatchQ[#, "star*"], True] &@dat $\endgroup$
    – user1066
    Commented Jun 13, 2016 at 23:51
  • $\begingroup$ @TomD, much nicer, thank you. Updated with that alternative. $\endgroup$
    – kglr
    Commented Jun 13, 2016 at 23:56
14
$\begingroup$

For large lists, this should be snappy:

Pick[Range@Length@dat, StringTake[dat, UpTo@4], "star"]

and actually, taking advantage of listability,

Pick[Range@Length@dat, StringMatchQ[dat, "star*"]]

is a bit faster it seems...

$\endgroup$
1
$\begingroup$
list =
  {"star", "u", "g", "r", "i", "z", "star2", "u", "g", 
   "r", "i", "z", "star3", "u", "g", "r", "i", "z", 
   "star4", "u", "g", "r", "i", "z","Astro", "u", "g", 
   "r", "i", "z"};

Using SelectIndices by Taliesin Beynon

SelectPositions = ResourceFunction["SelectIndices"];

SelectPositions[StringTake[#, UpTo @ 4] == "star" &] @ list

{1, 7, 13, 19}

$\endgroup$
1
$\begingroup$
list =
  {"star", "u", "g", "r", "i", "z", "star2", "u", "g", 
   "r", "i", "z", "star3", "u", "g", "r", "i", "z", 
   "star4", "u", "g", "r", "i", "z","Astro", "u", "g", 
   "r", "i", "z"};

Using PositionIndex and KeySelect:

Values[KeySelect[PositionIndex[dat], StringMatchQ[#, "star" ~~ ___] &]]

{{1}, {7}, {13}, {19}}

A variant using Position and StringContainsQ:

Position[dat, x_String /; StringContainsQ[x, "star"]]

{{1}, {7}, {13}, {19}}

$\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.