8
$\begingroup$

I have the following lists

A = {{1, 2, 3}, {1, 0, 3}};
B = {{1, 2}, {3, 4}, {4, 5}};

and I don't know how to join them to create a list C in the following way:

C = {{1, 2, 3, 1, 2}, {1, 2, 3, 3, 4}, {1, 2, 3, 4, 5},
     {1, 0, 3, 1, 2}, {1, 0, 3, 3, 4}, {1, 0, 3, 4, 5}}

That is, I want to join then as by Join[] but also 'multiply'.

My second question is how to do the same operation on A and B conditioned on the value of A[[;; , 2]]. Say, combine them as described only for A[[1 , 2]]=2 and ignore otherwise without relying on a loop.

$\endgroup$
  • 2
    $\begingroup$ Your second question is unclear to me, what output do you expect? $\endgroup$ – xzczd Aug 12 '16 at 2:28
  • $\begingroup$ I expect just this C = {{1, 2, 3, 1, 2}, {1, 2, 3, 3, 4}, {1, 2, 3, 4, 5}} because the second value of the second 'row' of A is not 2. $\endgroup$ – dzaohpeq Aug 12 '16 at 11:16
14
$\begingroup$

RememberOuter everytime you try to do something you call as 'multiply'.

Outer[Join, A, B, 1]

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

Join as the function, and A and B as two vectors, then do Outer at level 1 shall give you a proper result.

I don't know what you want for the second part of your question, but I suppose adding a filter directly to A will do the job:

Select[A,#[[2]]!=2&]
$\endgroup$
  • $\begingroup$ That is what I needed. Thanks. $\endgroup$ – dzaohpeq Aug 12 '16 at 11:14
7
$\begingroup$

This appears to be 7-10 times faster than Outer, depending of lists length:

 With[{l = Length[B]},
   Function[
      subA, Join[ConstantArray[subA, l], B, 2]
   ] /@ A
 ]
$\endgroup$
  • $\begingroup$ This solution is CONSIDERABLY faster than mine when A and B are huge, but not that fast when A and B are the simple situation OP posted. May I ask why this method will be faster in most cases? is this because of the reduced calls of Join? $\endgroup$ – Wjx Aug 12 '16 at 7:09
  • $\begingroup$ @Wjx I'm not an expert in performance tunning but notice that we are Joining here row by row instead of each pair. Also, Map autocompiles for larger lists (which I don't know if happens here). $\endgroup$ – Kuba Aug 12 '16 at 7:18
  • $\begingroup$ oh, maybe that's the case, thanks for your explanation! $\endgroup$ – Wjx Aug 12 '16 at 7:33
  • $\begingroup$ If I could accept two post I would do it here too because in reality my lists are huge. $\endgroup$ – dzaohpeq Aug 12 '16 at 11:24
  • 1
    $\begingroup$ Then you really should accept @Kuba's answer. I mean, his answer is better than mine for you, and I won't mind that 15 rep. $\endgroup$ – Wjx Aug 12 '16 at 11:51
6
$\begingroup$
Join @@@ Tuples[{A, B}]

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

or

Distribute[{A, B}, List, List, List, Join]

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

$\endgroup$
5
$\begingroup$

I know the best approach for your case is using Outer[] directly. Here is another method:

Table[Join[A[[i]], B[[j]]], {i, 1, 2}, {j, 1, 3}] // Flatten[#, 1] &

(*{{1, 2, 3, 1, 2}, {1, 2, 3, 3, 4}, {1, 2, 3, 4, 5}, 
   {1, 0, 3, 1, 2}, {1, 0, 3, 3, 4}, {1, 0, 3, 4, 5}}*)
$\endgroup$
4
$\begingroup$
A = {{1, 2, 3}, {1, 0, 3}}
B = {{1, 2}, {3, 4}, {4, 5}}

Table[Join[A[[l]], B[[n]]], {l, 1, 2, 1}, {n, 1, 3, 1}]
$\endgroup$
  • $\begingroup$ how did you make the gray rectangle Wjx? $\endgroup$ – Alucard Aug 12 '16 at 3:12
  • 1
    $\begingroup$ Highlight (drag) your code, and press the {} button $\endgroup$ – JungHwan Min Aug 12 '16 at 3:14
  • $\begingroup$ ah thanks, i did not know $\endgroup$ – Alucard Aug 12 '16 at 3:18
  • 1
    $\begingroup$ Also, if you want to @ someone, you should use @Wjx instead of directly typing it. I won't be mentioned if you directly type Wjx. :) $\endgroup$ – Wjx Aug 12 '16 at 3:29

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.