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$ 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$ 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$ Commented Jun 13, 2016 at 23:51
  • $\begingroup$ @TomD, much nicer, thank you. Updated with that alternative. $\endgroup$ 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$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.