8
$\begingroup$

I'm trying to learn more about list replacement without using Table. I have a list like this:

list = {{{"a", "b", "c"}, {"d", "e", "f"}, {"g", "h", "i"}}}

Now, I want to modify the list elements, i.e. add the position of the respective elements in front of it and replace every element in the list with that:

listMod = {{{1->"a", 2->"b",3->"c"}, {1->"d", 2->"e", 3->"f"}, {1->"g", 2->"h", 3->"i"}}}
$\endgroup$
2
  • 2
    $\begingroup$ Check MapIndexed. $\endgroup$
    – Kuba
    Aug 17, 2017 at 20:15
  • $\begingroup$ Ah yes that works quite well, thank you! $\endgroup$
    – holistic
    Aug 17, 2017 at 20:27

7 Answers 7

10
$\begingroup$
list = {{{"a", "b", "c"}, {"d", "e", "f"}, {"g", "h", "i"}}};
Map[MapIndexed[First@#2 -> #1 &], #, {2}] &@list

(* Out: {{{1 -> "a", 2 -> "b", 3 -> "c"}, {1 -> "d", 2 -> "e", 3 -> "f"},
        {1 -> "g", 2 -> "h", 3 -> "i"}}} *)
$\endgroup$
2
  • $\begingroup$ Thank you, didn't about MapIndexed until now ;) $\endgroup$
    – holistic
    Aug 17, 2017 at 20:27
  • 2
    $\begingroup$ @holistic You are very welcome :-) $\endgroup$
    – MarcoB
    Aug 17, 2017 at 20:28
6
$\begingroup$
list = {{{"a", "b", "c"}, {"d", "e", "f"}, {"g", "h", "i"}}};


Apply[Rule, Map[Transpose[{Range@3, #}] &, list, {2}], {3}]

enter image description here

Or, more generally

num[v_] := Thread[Range@Length@v -> v]

num /@ Catenate@list

Or

Normal @ Map[PositionIndex, list, {2}] /. (a_ -> {b_}) :> b -> a
$\endgroup$
1
  • $\begingroup$ Wow, thanks still trying to understand the last line ;) $\endgroup$
    – holistic
    Aug 17, 2017 at 20:29
5
$\begingroup$
MapIndexed[#2[[3]] -> #1 &, list, {3}]

{{{1 -> "a", 2 -> "b", 3 -> "c"}, {1 -> "d", 2 -> "e", 3 -> "f"}, {1 -> "g", 2 -> "h", 3 -> "i"}}}

Original answer

Map[Thread[Range@Length@# -> #] &, list, {2}]

 

MapIndexed[#2[[3]] -> #1 &, list, {3}] == 
Map[Thread[Range@Length@# -> #] &, list, {2}] == listMod

True

$\endgroup$
4
$\begingroup$

You can use ReplacePart :

list = {{{"a", "b", "c"}, {"d", "e", "f"}, {"g", "h", "i"}}}
ReplacePart[list,x:{i_,j_,k_}:> (k-> Extract[list,x])]  

{{{1 -> "a", 2 -> "b", 3 -> "c"}, {1 -> "d", 2 -> "e", 3 -> "f"}, {1 -> "g", 2 -> "h", 3 -> "i"}}}

ReplacePart[] is known to be not efficient in terms of memory consumption and speed.

The advantage here is that you have a great flexiblity to do more complicated remplacements. For example you can put constraints on the patterns i_,j_,k_,x

$\endgroup$
3
$\begingroup$
Module[{i = 1}, i++ -> # & /@ #] & /@ # & /@ list

{{{1 -> "a", 2 -> "b", 3 -> "c"}, {1 -> "d", 2 -> "e", 3 -> "f"}, {1 -> "g", 2 -> "h", 3 -> "i"}}}

$\endgroup$
3
$\begingroup$
MapThread[Rule, {ConstantArray[Range[#3],
     {#, #2}] & @@ Dimensions[list], list}, 3]

{{{1 -> "a", 2 -> "b", 3 -> "c"}, {1 -> "d", 2 -> "e", 3 -> "f"}, {1 -> "g", 2 -> "h", 3 -> "i"}}}

$\endgroup$
2
$\begingroup$

Missed the boat on this... The only thing I can think of that hasn't already appeared is

List@Transpose[With[{i = #}, i -> # & /@ list[[1, ;; , i]]] & /@ {1, 2, 3}]

Although & / @ {1, 2, 3} is basically Table, so I don't know if it counts.

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