# Deleting elements on a list by the first element of another list

I was trying to make this

L1 = {{2, 1}, {6, 4}, {8, 7}, {9, 5}};
L2 = {{2, 9}, {9, 6}};
L = Union[L2 , L1]


And I used this:

Cases[L, {{a_, _}, {b_, _}} /; a == b]
Complement[L,L2]


And this:

DeleteCases[L, MemberQ[L1, {#[[1]], _}] & /@ L2]


But, both fail. The answer must take from L1 only the elements where the first element appear in L2. For L1 and L2 above, must return

{{2,1},{9,5}}


And {6, 4} and {8, 7} must be dropped from L2!

Thanks,

• Commented Dec 18, 2013 at 0:58

Using Cases:

L1 = {{2, 1}, {6, 4}, {8, 7}, {9, 5}};
L2 = {{2, 9}, {9, 6}};

With[{a = Alternatives @@ L2[[All, 1]]}, Cases[L1, {a, _}]]

• And the complement to your answer: With[{a = Alternatives @@ L2[[All, 1]]}, DeleteCases[L1, {Except@a, _}]] :)
– rm -rf
Commented Dec 17, 2013 at 20:40
• Simon, why use With here? Clarity? Commented Dec 18, 2013 at 0:59
• @Mr.Wizard, yes, just for clarity. Not really necessary here, but I did some work recently with rather complex string patterns and got into the habit of doing this to make StringCases and StringMatchQ expressions more readable. Commented Dec 18, 2013 at 9:46
• Okay, just checking. I sometimes use Function the same way, e.g. Alternatives @@ L2[[All, 1]] // Cases[L1, {#, _}] &. Commented Dec 18, 2013 at 9:49
• Could you tell me if I am wrong: the command With will take the cases in L1 where a could be any of the first elements in the list L2 (2 and 9 for this example)...it is ok? Commented Dec 18, 2013 at 17:34
a = {{2, 1}, {6, 4}, {8, 7}, {9, 5}};
b = {{2, 9}, {9, 6}};


Using MapApply (new in 13.1)

KeyValueMap[List] @ First @ KeyIntersection[MapApply[Rule] /@ {a, b}]


{{2, 1}, {9, 5}}

From Documentation details:

"KeyIntersection can be used not only on Association objects, but also on lists of rules."

L1 = {{2, 1}, {6, 4}, {8, 7}, {9, 5}};
L2 = {{2, 9}, {9, 6}};
Select[L1, MemberQ[L2[[All, 1]], First@#] &]
(*
{{2, 1}, {9, 5}}
*)

• This will reevaluate L2[[All, 1]] for every element of L1. This is not ideal for long lists. Commented Dec 18, 2013 at 1:01
• @Mr.Wizard  When deciding whether to optimize a specific part of the program, Amdahl's Law should always be considered: the impact on the overall program depends very much on how much time is actually spent in that specific part, which is not always clear from looking at the code without a performance analysis. Commented Dec 18, 2013 at 1:37

Using the third argument of GroupBy:

L1 = {{2, 1}, {6, 4}, {8, 7}, {9, 5}};
L2 = {{2, 9}, {9, 6}};
L3 = Catenate@{L1, L2};

Catenate@GroupBy[L3, First, If[Length@# > 1, Complement[#, L2], {}] &]

(*{{2, 1}, {9, 5}}*)

a = {{2, 1}, {6, 4}, {8, 7}, {9, 5}};

b = {{2, 9}, {9, 6}};


Using Pick and ContainsAny

Pick[a, ContainsAny[First /@ b] /@ a]


{{2, 1}, {9, 5}}