7

Consider a set of rules, e.g.

{a -> aa, b -> bb, c -> cc, d -> dd, e -> ee}

I want to remove from this list all patterns of the form e->_ and to do so, I would like to form the Complement of matching patterns in my original set.

However if I use Cases, the description tells us that it has a special meaning, if a rule is given as second argument: The rule is applied to matching patterns after they have been identified.

Cases[{a, b, c, d, e, e}, e -> whow]

returns

{whow, whow}

because without the rule for e, {e,e} would be returned and this is transformed to {whow, whow} according to the given rule.

Now my example given above is such that the pattern to be searched for is a rule, namely

Rule[e,Blank[]]

As the explanation of Cases tells us, if a rule is input a second argument, the rule is applied to the matches. So

Cases[{a -> aa, b -> bb, c -> cc, d -> dd, e -> ee} , 
 Rule[e, Blank[]]]

returns an empty set because there is no match for e (in the set on the left, there is Rule[e,ee], not a pure e without anything around it. If I put Rule[e,Blank[] under Hold, the same happens.

Adalbert Hanßen
  • 2,808
  • 12
  • 26

2 Answers2

12

Under the Possible Issues tab of the Cases documentation.

Use HoldPattern to treat the rule itself as a pattern:

Cases[{a -> aa, b -> bb, c -> cc, d -> dd, e -> ee}, HoldPattern[e -> ee]]
(*{e -> ee}*)
Quantum_Oli
  • 7,964
  • 2
  • 21
  • 43
1
Select[{a -> aa, b -> bb, c -> cc, d -> dd, e -> ee} , 
 MatchQ[#, Rule[e, Blank[]]] &]

returns

{e->ee}

To remove all patterns involving e->_ use

Complement[#, Select[#, MatchQ[#, Rule[e, Blank[]]] &]] &  @  {a -> 
   aa, b -> bb, c -> cc, d -> dd, e -> ee}

Bingo!

After learning about HoldPattern, Verbatim and FilterRules in the siblings of my post (which I did not find before I posted), I constructed something which might be useful for others:

ComplementFilterRules[rules_List, patt_] := 
 Complement[rules, 
  FilterRules[rules, 
   patt]]; (* Exclude patt from a given list of rules: patt may be a 
single pattern or a list of patterns, only the lhs of those influence 
the result *)

and one step ahead in the management of options:

(* like ComplementFilterRules, but add the rules from the pattern and 
finally sort the result *)
OverrideFilterRules[rules_List, patt__ /; Length[{patt}] > 1] := 
 OverrideFilterRules[
  rules, {patt}];  (* the special case with more than 1 option 
argument *)

OverrideFilterRules[rules_List, patt_] := (* the general case *)
 Sort[Flatten[
   Union[Complement[rules, FilterRules[rules, patt]], {patt}]]];

application example:

OverrideFilterRules[{a -> aa, b -> bb,  c -> cc, d -> dd}, {b -> q, 
  d -> ddd}]
{a -> aa, b -> q, c -> cc, d -> ddd}

Thanks for pointing to the duplicates!

Adalbert Hanßen
  • 2,808
  • 12
  • 26
  • Maybe you require something like {a -> aa, b -> bb, c -> cc, d -> dd, e -> ee} /. (e -> _) :> Nothing (or am I missing something obvious)? – user1066 Apr 11 '16 at 09:52
  • Also, just for fun: FilterRules[yourList, Except[{e -> _}]] == Cases[yourList, Except[e -> _]] == (yourList /. (e -> _) :> Nothing) – user1066 Apr 11 '16 at 10:34
  • And (OverrideFilterRules[{a -> aa, b -> bb, c -> cc, d -> dd}, {b -> q, d -> ddd}]) == ({a -> aa, b -> bb, c -> cc, d -> dd} /. {(b -> bb) :> (b -> q), (d -> _) :> (d -> ddd) }) – user1066 Apr 11 '16 at 20:31