Cases with Alternatives failed
The issues with your code
There are two different issues here. First is that indeed, HoldPattern
would prevent Alternatives@@...
to evaluate. This is why
Cases[rules, HoldPattern[Alternatives @@ targets -> _]]
will not work. However, when you use
Cases[rules, HoldPattern[Evaluate[Alternatives @@ targets]] -> _]
you run into another issue: Cases
has an extended syntax Cases[expr, lhs_->rhs_,...]
, where it interprets Rule
as a part of its extended syntax, rather than a part of expression to be matched. Conceptually, the correct solution here would be, for example, to use Verbatim
to escape Rule
:
Cases[rules,Verbatim[Rule][HoldPattern[Evaluate[Alternatives @@ targets]], _]]
(* {a -> 1, b -> 2} *)
HoldPattern and Verbatim
However, I have to note that the whole business with HoldPattern
here seems either unnecessary or insufficient. If you don't worry about possible evaluation of a
, b
, etc, then you don't need HoldPattern
:
Cases[rules, Verbatim[Rule][Alternatives @@ targets, _]]
(* {a -> 1, b -> 2} *)
So, it looks like a classic case of misuse of HoldPattern
, where you use HoldPattern
where Verbatim
should be used.
OTOH, if you do worry about evaluations of a
, b
, etc, then you need to do a whole lot more to prevent their evaluation, than just in the line with Cases
. But this doesn't seem to be the case you are interested in.
HoldPattern
has attribute HoldAll
Attributes[HoldPattern]
(* {HoldAll, Protected} *)
So one can use the following injection
Cases[rules, HoldPattern[Alternatives@## -> _] & @@ targets]
(* {a -> 1, b -> 2} *)
P.S. Conceptually, HoldPattern
is here the wrong tool for the job, even if this works. See Leonid's answer.
This should probably be a comment (and maybe I have missed it):
This does not address the issue re: Alternatives
but note FilterRules
does this.
rules = {a -> 1, b -> 2, c -> 3};
FilterRules[rules, {a, b}]
or
rules = {a -> 1, b -> 2, c -> 3, d -> 4}
FilterRules[rules, {d, a, b}]
yields: {a -> 1, b -> 2, d -> 4}