3
$\begingroup$

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,

$\endgroup$
1

4 Answers 4

6
$\begingroup$

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, _}]]
$\endgroup$
6
  • $\begingroup$ And the complement to your answer: With[{a = Alternatives @@ L2[[All, 1]]}, DeleteCases[L1, {Except@a, _}]] :) $\endgroup$
    – rm -rf
    Dec 17, 2013 at 20:40
  • $\begingroup$ Simon, why use With here? Clarity? $\endgroup$
    – Mr.Wizard
    Dec 18, 2013 at 0:59
  • $\begingroup$ @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. $\endgroup$ Dec 18, 2013 at 9:46
  • $\begingroup$ Okay, just checking. I sometimes use Function the same way, e.g. Alternatives @@ L2[[All, 1]] // Cases[L1, {#, _}] &. $\endgroup$
    – Mr.Wizard
    Dec 18, 2013 at 9:49
  • $\begingroup$ 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? $\endgroup$
    – Jotasmall
    Dec 18, 2013 at 17:34
3
$\begingroup$
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."

$\endgroup$
2
$\begingroup$
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}}
*)
$\endgroup$
2
  • $\begingroup$ This will reevaluate L2[[All, 1]] for every element of L1. This is not ideal for long lists. $\endgroup$
    – Mr.Wizard
    Dec 18, 2013 at 1:01
  • $\begingroup$ @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.` $\endgroup$ Dec 18, 2013 at 1:37
1
$\begingroup$

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}}*)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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