# Get position while matching pattern

I want following imaginary feature : PositionOf

Example1)

In[1]  Cases[{3,5,1,7,2,8,9,7,5,6}, x_ /; x > 4 :> PositionOf[x]]

Out[1]  {2,4,6,7,8,9,10}


Above code extracts elements bigger than 4 (x_ /; x > 4),
{5,7,8,9,7,5,6}
and produce their position :> PositionOf[x]:
{2,4,6,7,8,9,10}

Example2)

In[2]  Cases[{3,5,1,7,2,8,9,7,5,6}, x_ /; x + PositionOf[x] == 14]

Out[2]  {8,5}


Above code extracts every element x such that x + its position is 14 (x_ /;x + PositionOf[x] == 14) In the list, 8 is 6th, and 5 is 9th. 8+6 = 5+9 = 14. So the output is {8,5}.

There is a code that works for example 1 :

Flatten[Position[{3,5,1,7,2,8,9,7,5,6}, x_ /; x > 4 ]]


also for example 2 by indexing method (using Range,Length,Transpose,Part.)

But I am curious that PositionOf[x] like feature is ever possible. If there is no such thing, a slight variation is also welcomed.

• Position already has this capability for your first example: Flatten[Position[{3, 5, 1, 7, 2, 8, 9, 7, 5, 6}, x_ /; x > 4]] returns {2,4,6,7,8,9,10} Commented Apr 13, 2021 at 15:31

With[{list = {3, 5, 1, 7, 2, 8, 9, 7, 5, 6}},
Select[14 == Plus @@ # &][Thread[{list, Range@Length@list}]]
][[All, 1]]
(* returns : {8, 5} *)


Another way using ResourceFunction["PositionCases"]:

PositionCases = ResourceFunction["PositionCases"];
PositionCases[{3, 5, 1, 7, 2, 8, 9, 7, 5, 6},
PositionPattern[pos_, x_] /; pos != {} && First[pos] + x == 14]
(* returns : {8, 5} *)

list = {3, 5, 1, 7, 2, 8, 9, 7, 5, 6};

Cases[MapIndexed[List] @ list, {a_, {b_}} /; a + b == 14 -> a]


{8, 5}

list = {3, 5, 1, 7, 2, 8, 9, 7, 5, 6};


Using the third argument of GroupBy:

GroupBy[Thread[{#, Range@Length@#}] &@list, Total@# == 14 &, First /@ # &][True]

(*{8, 5}*)

a = {3, 5, 1, 7, 2, 8, 9, 7, 5, 6};
Pick[a, MapIndexed[#1 + #2[[1]] &, a], 14]


yields {8,5}

Or:

Pick[a, 14 - a - Range[Length[a]], 0]

• Or more briefly, Pick[a, MapIndexed[Plus, a], {14}] (+1) Commented Mar 7 at 14:49
• @Goofy yes indeed Commented Mar 7 at 21:30

The problem is concerned only with the index at level 1 and not with general positions. Here is another solution to example 2 along those lines:

{3, 5, 1, 7, 2, 8, 9, 7, 5, 6} //
Module[{idx = 0}, Cases[#, x_ /; ++idx + x == 14]] &

(* {8, 5} *)