7
$\begingroup$

Given

 t1 = {{1, 2}, {3, 4}};
 t2 = {{a, b, c}, {e, f}};

I want to add in succession elements of list 2 to list 1 to get:

{{1, 2, a}, {1, 2, b}, {1, 2, c}, {3, 4, e}, {3, 4, f}}

I can do it by:

Flatten[MapThread[Flatten /@ Tuples[{{#1}, #2}] &, {t1, t2}], 1]

as indicated in Thread over list in different levels. This is pretty rough. Any ideas how to do it in a reasonable concise way and easier to understand?

$\endgroup$

4 Answers 4

9
$\begingroup$

Your method is quite concise.

You can also do:

MapThread[## & @@ Thread[{## & @@ #, #2}] &]@{t1, t2}

Join @@ MapThread[Thread[{## & @@ #, #2}] &] @ {t1, t2}

Join @@ MapThread[Flatten /@ Thread[{##}, List, {2}] &] @ {t1, t2}

Join @@ MapThread[Function[{a, b}, Append[a, #] & /@ b]] @ {t1, t2}

Join @@ Map[Flatten]@*Tuples /@ Thread[{List /@ t1, t2}]

to get

{{1, 2, a}, {1, 2, b}, {1, 2, c}, {3, 4, e}, {3, 4, f}}

And a Halloween special:

enter image description here

☺ = {## & @@ #, #2} /. 
      {♯__, ♯♯ : {__}} :>
       (## & @@ ({♯, #} & /@ ♯♯)) & @@@
    ({##}\[Transpose]) &;

☺[t1, t2]
 {{1, 2, a}, {1, 2, b}, {1, 2, c}, {3, 4, e}, {3, 4, f}}
$\endgroup$
7
  • 1
    $\begingroup$ First I thought your last solution is a joke! But it really works! I am still struggling to understand your other solutions but concerning this last one, I think I will come back to you X-mas next year! $\endgroup$
    – user57467
    Oct 14, 2020 at 10:55
  • 1
    $\begingroup$ @user57467, Apply[## &, {t1, t2}, 2]? $\endgroup$
    – kglr
    Oct 14, 2020 at 20:53
  • 2
    $\begingroup$ @user57467, foo = Thread[{## & @@ #, #2}] & is a pure function ( a function with unnamed arguments) that does the same thing as the function bar[x_,y_] := Thread[{Apply[Sequence][x],y}]. The function ##& is the function Sequence, andt he form buz@@x is the same as Apply[buz][x] (see Apply). The symbols # (Slot ), #2,`#3,...represent the first, second,third,... arguments supplied to a function. $\endgroup$
    – kglr
    Oct 17, 2020 at 18:35
  • 1
    $\begingroup$ ... To see the reason for using Apply[Sequence] on the first argument, let x={2,4,5};y={u,v}; and try Thread[{Apply[Sequence][x],y}] vs Thread[{x,y}]. $\endgroup$
    – kglr
    Oct 17, 2020 at 18:40
  • 1
    $\begingroup$ ... and see this flash animation on how Thread works on a list of lists. $\endgroup$
    – kglr
    Oct 17, 2020 at 18:44
6
$\begingroup$

Given:

t1 = {{1, 2}, {3, 4}};
t2 = {{a, b, c}, {e, f}};

ReplacePart can express the transformation reasonably directly:

ReplacePart[t2, {i_,j_} :> Append[t1[[i]], t2[[i,j]]]] // Catenate


(* {{1,2,a},{1,2,b},{1,2,c},{3,4,e},{3,4,f}} *)

The same technique is textually shorter using MapIndexed, but perhaps a little less readable:

MapIndexed[Append[t1[[#2[[1]]]], #] &, t2, {2}] // Catenate

(* {{1,2,a},{1,2,b},{1,2,c},{3,4,e},{3,4,f}} *)
$\endgroup$
5
$\begingroup$

I also use Outer to construct the list.

t1 = {{1, 2}, {3, 4}};
t2 = {{a, b, c}, {e, f}};
MapThread[
  Outer[Flatten@*List, {#1}, #2, 1]~Flatten~1 &, {t1, t2}]~Flatten~1
Flatten /@ MapThread[Outer[List, {#1}, #2, 1] &, {t1, t2}]~Flatten~2
$\endgroup$
4
$\begingroup$

Or using CartesianProduct from Combinatorica package

t1 = {{1,2},{3,4}};
t2 = {{a,b,c},{e,f}};

Needs["Combinatorica`"]
  
Flatten /@ Catenate @ MapThread[CartesianProduct,{List[#]& /@ t1,t2}]
$\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.