5
$\begingroup$

I've these two lists:

l1 = {{a, 1}, {b, 2}, {c, 3}, {d, 4}};
l2 = {{b, 5}, {d, 6}, {f, 7}};

Every list element is a two-coordinates point. I want to retrieve elements of both lists that have the first coordinate in common with the other list.

In the example we can see that the lists have in common the b and d first element coordinate. I can find it with following command:

commonIndices = Intersection[l1[[;; , 1]], l2[[;; , 1]]]

It returns {b, d}. What I want to do now is to elaborate this result in order to obtain these lists:

ll1 = {{b, 2}, {d, 4}};
ll2 = {{b, 5}, {d, 6}};

that are the sublists of l1 and l2 that have as first coordinate one of the indices found with previous command.

Ho can I obtain this result?

$\endgroup$
  • $\begingroup$ I think you should wait a bit longer before accepting an answer, next time. I also don't mind if you decide to redistribute the acception, e.g. to aardvark2012's answer. It is definately much faster than mine for large lists. $\endgroup$ – Henrik Schumacher Nov 27 '17 at 11:37
5
$\begingroup$
ll1 = Select[l1, MemberQ[commonIndices, #[[1]]] &]
ll2 = Select[l2, MemberQ[commonIndices, #[[1]]] &]

{{b, 2}, {d, 4}}

{{b, 5}, {d, 6}}

$\endgroup$
  • $\begingroup$ Thanks a lot, this is what I needed. $\endgroup$ – Jepessen Nov 27 '17 at 11:10
  • $\begingroup$ You're welcome! $\endgroup$ – Henrik Schumacher Nov 27 '17 at 11:11
5
$\begingroup$

You can get the result as an Association with

KeyIntersection[AssociationThread @@ Transpose[#] & /@ {l1, l2}]

(* {<|b -> 2, d -> 4|>, <|b -> 5, d -> 6|>} *)

If you want it as a list:

{ll1, ll2} = % /. Association | Rule -> List

(* {{{b, 2}, {d, 4}}, {{b, 5}, {d, 6}}} *)
$\endgroup$
  • $\begingroup$ That's a great one. You can speed it up even more by using AssociationThread. $\endgroup$ – Henrik Schumacher Nov 27 '17 at 11:24
  • $\begingroup$ @HenrikSchumacher Awesome. Thanks for that. $\endgroup$ – aardvark2012 Nov 27 '17 at 11:27
3
$\begingroup$

You do not have to use commonIndices:

ll1=Intersection[l1, l2, SameTest -> (First[#1] === First[#2] &)]
ll2=Intersection[l2, l1, SameTest -> (First[#1] === First[#2] &)]
$\endgroup$
  • $\begingroup$ Note that the essential part of the intersection gets computed twice this way. $\endgroup$ – Henrik Schumacher Nov 27 '17 at 11:18
  • $\begingroup$ @HenrikSchumacher That's true. $\endgroup$ – Αλέξανδρος Ζεγγ Dec 1 '17 at 15:09

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.