9
$\begingroup$

Here is what I have done.

Input

DeleteCases[{{x -> a}, {x -> b}, {x -> c, x -> d}}, Rule, {2}]

Output

{{x -> a}, {x -> b}, {x -> c, x -> d}}

Why is it not {{x, a}, {x, b}, {{x, c}, {x, d}}}?

$\endgroup$
1
  • $\begingroup$ {{x -> a}, {x -> b}, {x -> c, x -> d}} /. (x_ -> a_) :> {x, a} /. {{a__}} :> {a} also works. $\endgroup$ Commented Feb 16, 2020 at 13:58

4 Answers 4

14
$\begingroup$

DeleteCases does not by default operate on heads. You can set the Heads option to True to change that.

DeleteCases[{{x -> a}, {x -> b}, {x -> c, x -> d}}, Rule, {3}, Heads -> True]
{{x, a}, {x, b}, {x, c, x, d}}

Note that the last term has become {x, c, x, d} which is not quite what you expected, but it is logically consistent if we expect {x -> a} to become {x, a}.

A simpler path to the same output in this case is:

{{x -> a}, {x -> b}, {x -> c, x -> d}} /. Rule -> Sequence
{{x, a}, {x, b}, {x, c, x, d}}

Your expected output can be had from:

{{x -> a}, {x -> b}, {x -> c, x -> d}} /. Rule -> List /. {x_List} :> x
{{x, a}, {x, b}, {{x, c}, {x, d}}}

Recommended reading:

$\endgroup$
2
  • $\begingroup$ Is it possible to use Apply to 2nd levelspec? $\endgroup$
    – kile
    Commented Feb 17, 2020 at 9:51
  • 1
    $\begingroup$ @kile Yes! You could write Apply[Sequence, {{x -> a}, {x -> b}, {x -> c, x -> d}}, {2}] But understand that Sequence must evaluate, so this is not directly deleting the head. See the "Recommended reading" link for details. $\endgroup$
    – Mr.Wizard
    Commented Feb 17, 2020 at 11:55
4
$\begingroup$

Replacing heads is generically supported by Apply (@@ / @@@). So a functional way may look like this:

rules = {{x -> a}, {x -> b}, {x -> c, x -> d}};
If[Length[#] == 1, Flatten[#], Identity[#]] & /@ Apply[List, rules, {-2}]
{{x, a}, {x, b}, {{x, c}, {x, d}}}

Or

If[Length[#] == 1, Sequence @@@ #, List @@@ #] & /@ rules

returns the same result.

$\endgroup$
2
$\begingroup$
rules = {{x -> a}, {x -> b}, {x -> c, x -> d}};

rules /. x : {_Rule, __} :> List @@@ x /. Rule :> Splice @* List

{{x, a}, {x, b}, {{x, c}, {x, d}}}

$\endgroup$
2
$\begingroup$
rules = {{x -> a}, {x -> b}, {x -> c, x -> d}};

Using Delete:

f = Function[s, If[Length@s == 1, List@Delete[First@s, 0], 
    Map[List@*Delete[0]]@s]];

f /@ rules

{{x, a}, {x, b}, {{x, c}, {x, d}}}

$\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.