Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Suppose that I have a list myList that has more than one level. Here is an example of such a "data structure":

myList = {{10, "c"}, {20, "a"}, {30, "b"}};

Now suppose that I have a list of characters, called charList:

charList = {"a", "b", "c"};

I want to use Position to find the positions of the charList characters in myList. Of course, I can do this manually -- by calling Position for each character in charList:

Position[myList, _?(#[[2]] == "a" &), {1}, Heads -> False]
Position[myList, _?(#[[2]] == "b" &), {1}, Heads -> False]
Position[myList, _?(#[[2]] == "c" &), {1}, Heads -> False]

{{2}}

{{3}}

{{1}}

And, of course, I can shorten this process by using Table to call Position repeatedly:

Table[
 Position[myList, _?(#[[2]] == charList[[i]] &), {1}, Heads -> False], 
{i, 1, Length[charList]}]

{{{2}}, {{3}}, {{1}}}

But, is it possible to shorten the code even more by using Map? (I often find Map more convenient and easier to read than Table.) My initial thought was to do something like this:

Map[
 Position[myList, _?(#[[2]] == # &), {1}, Heads -> False] &,
charList]

but I get undesired output:

{{}, {}, {}}

I think that I have failed to distinguish between the two different # slots, which refer to two different things (they refer to different &s). How can I distinguish the two # so that I can Map Position across charList?

share|improve this question
    
Even with Table it can be quite neater Table[Position[myList, {_, i,___}, {1}, Heads -> False], {i, charList}] –  Rojo Jan 15 at 22:09
1  
Since there is nice answer this is a comment how to deal with those slots ambiguity (not neat, just straightforward) Map[Function[x, Position[myList, _?(#[[2]] == x &), {1}, Heads -> False]], charList] –  Kuba Jan 15 at 22:11
    
p.s. related –  Kuba Jan 15 at 22:19
    
Another related question, in fact my own very first question. –  Pickett Jan 15 at 22:37
add comment

3 Answers 3

up vote 4 down vote accepted

Shorter:

Position[myList, {_, #}] & /@ charList

Since I feel that the answer is a little short, here's another way:

charList /. MapIndexed[Last@# -> First@#2 &, myList]
share|improve this answer
add comment

Using the OP's original form, distinguish the charList parameter using Function:-

myList = {{10, "c"}, {20, "a"}, {30, "b"}};

charList = {"a", "b", "c"};

Map[
 Function[x, Position[myList, _?(#[[2]] == x &), {1}, Heads -> False]],
 charList]

{{{2}}, {{3}}, {{1}}}

share|improve this answer
add comment

Although I think Anon's:

Position[myList, {_, #}] & /@ charList

is the neatest, here is an approach using Sow and Reap:

fun[u_, v_] := 
 Module[{c = 1}, Join @@ Reap[Sow[c++, Last@#] & /@ u, v, Rule][[2]]]

For example:

fun[myList, charList]

yields:

{"a" -> {2}, "b" -> {3}, "c" -> {1}}

or a list with multiple characters, e.g.

test={{10, "c"}, {20, "a"}, {30, "b"}, {1, "a"}};

then

fun[test,charList]

gives:

{"a" -> {2, 4}, "b" -> {3}, "c" -> {1}}

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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