1
$\begingroup$

I have the following example:

data = {{a, a1, a2}, {b, b1, b2}, {c, c1, c2}, {d, d1, d2}};
repa = {a11, a12, a13};
repb = {b11, b12, b13};
repc = {c11, c12, c13};
newData = 
 MapThread[
  ReplacePart[data, {{1, 2} -> #1, {2, 2} -> #2}] &, {repa, repb}]

Which generates:

{{{a, a11, a2}, {b, b11, b2}, {c, c1, c2}, {d, d1, d2}}, {{a, a12, 
   a2}, {b, b12, b2}, {c, c1, c2}, {d, d1, d2}}, {{a, a13, a2}, {b, 
   b13, b2}, {c, c1, c2}, {d, d1, d2}}}

Now, what if I want to continue in a similar way, and generate on this the following:

{...,{{a, a11, a2}, {b, b11, b2}, {c, c11, c2}, {d, d1, d2}}, {{a, a12, 
       a2}, {b, b12, b2}, {c, c12, c2}, {d, d1, d2}}, {{a, a13, a2}, {b, 
       b13, b2}, {c, c13, c2}, {d, d1, d2}}}

where the dots represent the expression above without the outer {} or even something uglier by making the copy of the above and then extending it by replacing d1->{d11,d12,d13} analogously? What would be the best way? Also is there a way without stacking the operators which implies that i have to know how many variations I need to make?

Also I would be glad with any comments, on the current implementation of MapThread+ReplacePart, is there a better way?

$\endgroup$
  • $\begingroup$ At least, you can do MapThread[ReplacePart[data, {{1, 2} -> #1, {2, 2} -> #2, {3, 2} -> #3, {4, 2} -> #4}] &, {repa, repb, repc, repd}], because MapThread is generalizable to more than two inputs, but there's certainly a better way. I will think on it. $\endgroup$ – march Mar 12 '16 at 0:29
1
$\begingroup$

The direct generalization of your code would be to take advantage of the fact that MapThread works for functions with more than two arguments. Therefore, if

data = {{a, a1, a2}, {b, b1, b2}, {c, c1, c2}, {d, d1, d2}};
repa = {a11, a12, a13};
repb = {b11, b12, b13};
repc = {c11, c12, c13};
repd = {d11, d12, d13};

then

newData = MapThread[
   ReplacePart[data, {{1, 2} -> #1, {2, 2} -> #2, {3, 2} -> #3, {4, 2} -> #4}] &,
   {repa, repb, repc, repd}
  ]
(* { {{a, a11, a2}, {b, b11, b2}, {c, c11, c2}, {d, d11, d2}},
     {{a, a12, a2}, {b, b12, b2}, {c, c12, c2}, {d, d12, d2}},
     {{a, a13, a2}, {b, b13, b2}, {c, c13, c2}, {d, d13, d2}} } *)

We can automate this somewhat via the following:

newData = With[
   {f = Table[{j, 2} -> Slot[j], {j, 4}]},
   MapThread[ReplacePart[data, f] &, {repa, repb, repc, repd}]
  ]

The following method has the advantage of not requiring hard-coding the number of lists (i.e. 4 for a, b, c, and d in this case), but it has the disadvantage of not working if there are repeated elements in the each sublist of data:

newData = Transpose@MapThread[
   #1 /. List /@ Thread[#1[[2]] -> #2] &,
   {data, {repa, repb, repc, repd}}
  ]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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