Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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!

share|improve this question

marked as duplicate by Mike Honeychurch, Sjoerd C. de Vries, rm -rf Dec 18 '12 at 15:15

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

2  
This is barely different from your previous question and those answers should provide you with the way to go with this one. –  Mike Honeychurch Dec 18 '12 at 10:25

4 Answers 4

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

list1 /. {i_Integer, x_} :> 
       {i, x, i /. Apply[Rule, list2, {1}]}
share|improve this answer
    
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

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"}}  *)
share|improve this answer
    
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: mathematica.stackexchange.com/questions/16507/…. –  Mike Honeychurch Dec 18 '12 at 19:48

Another way:

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

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

share|improve this answer

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

share|improve this answer

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