2

Possible Duplicate:
How do I obtain an intersection of two or more list of lists conditioned on the first element of each sub-list?

I would like to combine two lists.

list1 = {{134, 12}, {136, 14}, {140, 45}}

and

list2 = {{134, "B"}, {135, "A"}, {136, "E"}, {137, "A"}, {138,"I"}, {139, "B"}, {140, "G"}}

the result should be:

result = {{134, 12, "B"}, {136, 14, "E"}, {140, 45, "G"}}

Thank you very much!

RMMA
  • 2,710
  • 2
  • 18
  • 33

4 Answers4

5

One possibility (not optimized for speed, but readability) :

list1 /. {i_Integer, x_} :> 
       {i, x, i /. Apply[Rule, list2, {1}]}
Rolf Mertig
  • 17,172
  • 1
  • 45
  • 76
  • Rolf that is far more concise than any of the answers to yesterdays question. You should post your answer there in case this question gets closed. – Mike Honeychurch Dec 18 '12 at 10:59
  • @MikeHoneychurch o.k., did so, but had to add a MemberQ, so probably this is not that efficient. But I often trade efficiency for readability these days. – Rolf Mertig Dec 18 '12 at 12:17
  • I prefer readability as well unless the speed differences are too large to be ignored. – Mike Honeychurch Dec 18 '12 at 19:44
2

the answers to this question will work for you. Just Flatten the final lists

processList[list1_, list2_] := 
 Module[{intersection, tmp1, tmp2},
  intersection = Intersection[list1[[All, 1]], list2[[All, 1]]];
  tmp1 = Cases[list1, {x_ /; MemberQ[intersection, x], __}];
  tmp2 = Cases[list2, {x_ /; MemberQ[intersection, x], __}];
  Flatten[{#[[1, 1]], ##[[All, 2]]}] & /@ 
   GatherBy[Join[tmp1, tmp2], First]
  ]

processList[list1, list2]
(* {{134, 12, "B"}, {136, 14, "E"}, {140, 45, "G"}}  *)
Mike Honeychurch
  • 37,541
  • 3
  • 85
  • 158
  • thank you for this solution. how could I adopt it if one or both lists would have more than one column which should be copied. – RMMA Dec 18 '12 at 13:23
  • @Frink Your last question dealt specifically with matching more than one column. There is also this which might be a guide for your generic question: http://mathematica.stackexchange.com/questions/16507/how-to-sum-over-duplicates/16508#16508. – Mike Honeychurch Dec 18 '12 at 19:48
2

Another way:

Join[list1, List /@ Last /@ Select[list2, MemberQ[First /@ list1, #[[1]]] &], 2]

{{134, 12, "B"}, {136, 14, "E"}, {140, 45, "G"}}

VLC
  • 9,818
  • 1
  • 31
  • 60
2

As Mike told there was a very well written answer to your previous question that may address this question too. I show another way using pattern replacement for this purpose.

First form this rule

rule=(# /. List -> Rule) & /@ list2

{134 -> "B", 135 -> "A", 136 -> "E", 137 -> "A", 138 -> "I", 139 -> "B", 140 -> "G"}

Now we take the first column of list1 and apply the rule.

column3rd=list1[[All, 1]] /. rule

{"B", "E", "G"}

Now form your expected list by joining the above list with the other two existing columns

(Transpose[list1]~Join~{column3rd}) // Transpose

{{134, 12, "B"}, {136, 14, "E"}, {140, 45, "G"}}

BR

PlatoManiac
  • 14,723
  • 2
  • 42
  • 74