# How to apply a function to one part while keeping the rest?

I have a list and want to apply a function just on the second Part and keep the rest.

t1 = Table[{k, 2^k + 1}, {k, 2, 7}]


yielding

{{2, 5}, {3, 9}, {4, 17}, {5, 33}, {6, 65}, {7, 129}}


I want to FactorInteger the second part to get

 {{2, {5}}, {3, {3}}, {4, {17}}, {5, {3, 11}}, {6, {5, 13}}, {7, {3, 43}}}


By not using Cases like

 Cases[t1, {a_, b_} :> {a, FactorInteger[b][[All, 1]]}]


but by applying a function (maybe Hold or HoldPattern) which leaves k untouched when applying FactorInteger on the whole of t1. (I hope it makes sense what I am looking for.)

MapAt[Map[First] @* FactorInteger, {All, 2}] @ t1

{{2, {5}}, {3, {3}}, {4, {17}}, {5, {3, 11}}, {6, {5, 13}}, {7, {3,  43}}}

SubsetMap[#[[All,All,1]]& @* FactorInteger, {All, 2}] @ t1

{{2, {5}}, {3, {3}}, {4, {17}}, {5, {3, 11}}, {6, {5, 13}}, {7, {3,  43}}}

{#, FactorInteger[#2][[All, 1]]} & @@@ t1

{{2, {5}}, {3, {3}}, {4, {17}}, {5, {3, 11}}, {6, {5, 13}}, {7, {3,  43}}}

Module[{t = #},
t[[All, 2]] = FactorInteger[t[[All, 2]]][[All, All, 1]]; t] & @ t1

{{2, {5}}, {3, {3}}, {4, {17}}, {5, {3, 11}}, {6, {5, 13}}, {7, {3, 43}}}

• What does @* do? I can't find this in the docs. Jul 9, 2020 at 5:08
• @1110101001, see Composition
– kglr
Jul 9, 2020 at 5:11
MapAt[FactorInteger[#][[;; , 1]] &, t1, {All, 2}]


Rule approach starts with

rule1 = {x_,y_} :> {x, First /@ FactorInteger[y]};


and then

Replace[z1,rule1,{1}]


gives

    {{2,{5}},{3,{3}},{4,{17}},{5,{3,11}},{6,{5,13}},{7,{3,43}}}

t1//Transpose[{#[[All,1]],FactorInteger[#[[All,2]]][[All,All,1]]}]&


{{2, {5}}, {3, {3}}, {4, {17}}, {5, {3, 11}}, {6, {5, 13}}, {7, {3, 43}}}

As Inner may be thought of as a generalized form of dot, a function may also be applied only to the y values as follows:

Inner[Times,t1,{1,1},{#1,FactorInteger[#2][[All,1]]}&]


{2, {5}}, {3, {3}}, {4, {17}}, {5, {3, 11}}, {6, {5, 13}}, {7, {3, 43}}}

Fun with Inner/Dot

ll={{a,b},{c,d}}


To multiply all y values by 10:

ll.{{1,0},{0,10}}
Inner[#1 #2&, ll, {1,1},{#1,10 #2}&]

(*
{{a, 10 b}, {c, 10 d}}
{{a, 10 b}, {c, 10 d}}
*)


Or:

ll.{{1,0},{0,10}}==
Inner[#1 #2&, ll, {1,1},{#1,10 #2}&]==
Inner[Times, ll, {1,1},{#1,10 #2}&]==
Inner[Times, ll, {{1,0},{0,10}}]


True

To apply a function only to the y values of ll:

Inner[Times,ll,{1,1},{#1,f@#2}&]

(* {{a, f[b]}, {c, f[d]}} *)


Another option, /@ is usually my go-to for these sorts of things

f := FactorInteger[#][[All,1]]&

{#[[1]], f@#[[2]]} & /@ t1

list = {{2, 5}, {3, 9}, {4, 17}, {5, 33}, {6, 65}, {7, 129}};


Using Cases

Cases[{a_, b_} :> {a, First /@ FactorInteger[b]}] @ list


{{2, {5}}, {3, {3}}, {4, {17}}, {5, {3, 11}}, {6, {5, 13}}, {7, {3, 43}}}

list = {{2, 5}, {3, 9}, {4, 17}, {5, 33}, {6, 65}, {7, 129}};


Using SequenceCases:

SequenceCases[list, {{a_, b_}} :> {a, First /@ FactorInteger[b]}]


Result:

{{2, {5}}, {3, {3}}, {4, {17}}, {5, {3, 11}}, {6, {5, 13}}, {7, {3, 43}}}

Or using ReplaceList:

ReplaceList[list, {___, {a_, b_}, ___} :> {a, First /@ FactorInteger[b]}]


Result:

{{2, {5}}, {3, {3}}, {4, {17}}, {5, {3, 11}}, {6, {5, 13}}, {7, {3, 43}}}

Or using MapThread:

MapThread[{#1, First /@ FactorInteger@#2} &, Thread[list]]


Result:

{{2, {5}}, {3, {3}}, {4, {17}}, {5, {3, 11}}, {6, {5, 13}}, {7, {3, 43}}}

t0 = Table[{k, 2^k + 1}, {k, 2, 7}]


{{2, 5}, {3, 9}, {4, 17}, {5, 33}, {6, 65}, {7, 129}}

Define:

f = If[PrimeQ[#], {#}, Most@Rest@Divisors[#]] &;

t1 = SubsetMap[Map[f], t0, {All, 2}]


{{2, {5}}, {3, {3}}, {4, {17}}, {5, {3, 11}}, {6, {5, 13}}, {7, {3,
43}}}

It is not the actual question, but the post-processing step can be avoided altogether:

t2 = Table[{k, f[2^k + 1]}, {k, 2, 7}]


(* same output *)