Perform operations on the second component of each item in a list in Mathematica

I can use the following method to perform some operation (in this case, ToString ) for the first component of each item in the list:

 { ToString@ #[[1]], Rest@ #}~Flatten~1 & /@ {{1, 2}, {3, 4, 5}} 

However, I have a few questions:

  • This does not work for { ToString@ #[[1]], Rest@ #}~Flatten~1 & /@ {{1, 2}, 2, {3, 4, 5}} for obvious reason. How to do this thing? The expected result will be {{"1", 2}, 2, {"3", 4, 5}} .
  • How to do this for the second (or third, etc.) component easily ? That is, I want the result to be {{0}, {1, "2"}, {3, "4", 5}, {6, "7", 9, 10}}
  • Is there a way to use a template / rule (for example, /. /.{#[[1]]->ToString[#[[1]]]} - /.{#[[1]]->ToString[#[[1]]]} ) for this kind of operation? Therefore, please list all the solutions you may think of, regardless of effectiveness.

Thanks a lot!

+4
source share
4 answers

I did not understand that this is the same as the main function of Leonid, until I wrote this. However, perhaps this suggests that it may be slightly more transparent than its rather complex function.

 lst = {{1, 2}, 2, {3, 4, 5}}; Replace[lst, {a_, b__} :> { ToString@a , b}, 1] 
  {{"1", 2}, 2, {"3", 4, 5}} 

Then you can use {x:Repeated[_, {4}], a_, b__} :> {x, ToString@a , b}, 1] for the fifth index, etc.

+5
source

The following function should basically do what you want:

 ClearAll[applyToAll]; applyToAll[f_, list_List, n_Integer] := applyToAll[x_ :> f[x], list, n]; applyToAll[rule : (_Rule | _RuleDelayed), list_List, n_Integer] := Replace[ list, {left : Repeated[_, {n - 1}], el_, rest___} :> {left, el /. rule, rest}, {1}]; 

and can accept the rules. For instance:

 In[192]:= applyToAll[ToString, {{1,2},2,{3,4,5}},1]//InputForm Out[192]//InputForm= {{"1", 2}, 2, {"3", 4, 5}} In[193]:= applyToAll[ToString,{{0},{1,2},{3,4,5},{6,7,9,10}},2]//InputForm Out[193]//InputForm= {{0}, {1, "2"}, {3, "4", 5}, {6, "7", 9, 10}} In[194]:= applyToAll[x_?OddQ:>ToString[x],{{0},{1,2},{3,4,5},{6,7,9,10}},2]//InputForm Out[194]//InputForm= {{0}, {1, 2}, {3, 4, 5}, {6, "7", 9, 10}} 
+4
source

Another convenient way would be to use ReplacePart with RuleDelayed

For example, to turn part 3 of each subscription (if it exists) into a string:

 ReplacePart[#, 3 :> ToString@ #[[3]]] & /@ {{1, 2}, 2, {3, 4, 5}, {6, 7, 9, 10}} // InputForm 

gives as output:

{{1, 2}, 2, {3, 4, "5"}, {6, 7, "9", 10}}

Similarly, to turn part 1 of each subscription into a string:

 ReplacePart[#, 1 :> ToString@ #[[1]]] & /@ {{1, 2}, 2, {3, 4, 5}} // InputForm 

giving:

{{"1", 2}, 2, {"3", 4, 5}}

+2
source

In the long run, I think this may be a simpler approach, even if this is not quite what you asked for:

 rep[f_, pos_][x_List] := MapAt[f, x, pos] rep[__][x_] := x lst = {{1, 2}, 2, {3, 4, 5}}; rep[ToString, 2] /@ lst 
  {{1, "2"}, 2, {3, "4", 5}} 

You can add custom patterns and conditions to the rep definition as needed.

+1
source

Source: https://habr.com/ru/post/1388053/


All Articles