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$
1
  • $\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$ 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$
2
  • $\begingroup$ Thanks a lot, this is what I needed. $\endgroup$
    – Jepessen
    Nov 27 '17 at 11:10
  • $\begingroup$ You're welcome! $\endgroup$ 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$
2
  • $\begingroup$ That's a great one. You can speed it up even more by using AssociationThread. $\endgroup$ Nov 27 '17 at 11:24
  • $\begingroup$ @HenrikSchumacher Awesome. Thanks for that. $\endgroup$ 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$
2
  • $\begingroup$ Note that the essential part of the intersection gets computed twice this way. $\endgroup$ 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.