7
$\begingroup$

When evaluating the following input:

<|a -> {c, d, e}|> /. d -> Nothing

I get (expression 1):

<|a -> {c, Nothing, e}|>

However I would expect to get (expression 2):

<|a -> {c, e}|>

Nevertheless, if i place the cursor on the unexpected output (expression 1) and evaluate it by pressing Shift + Enter, I get the expected output (expression 2), which is even more puzzling.

Mathematica version is 11.0.0.0

Should this behaviour be expected or is it a bug? Why?

$\endgroup$
8
$\begingroup$

The observed puzzle is resolved by the following two observations:

From Leonid's answer in the linked q/a:

  • Association is HoldAllComplete. Once it is created, its parts will then normally be held unevaluated.

From Nothing>> Details

  • Nothing is removed as part of the standard evaluation process. It is not removed in expressions that are held or inactive.

You can Map ReplaceAll on the association to force removal of Nothings:

ReplaceAll[d -> Nothing] /@ assoc (* or *)
Map[# /. d -> Nothing &]@<|a -> {c, d, e}|>

<|a -> {c, e}|>

$\endgroup$
3
$\begingroup$

Pattern matching to a function evaluation inside an Association answers your question about bug vs expected result.

This will not do what your input suggests but let me anticipate your needs:

<|a -> {b, c, d}, e :> {d, Print[1], d}, f -> d|> //. 
  {a___, d, b___} :> {a, b} /. (*this way Print is not evaluated*)
  d -> Nothing 
<|a -> {b, c}, e :> {Print[1]}, f -> Nothing|>
$\endgroup$
5
$\begingroup$

Use Replace with level spec All rather than ReplaceAll:

Replace[<|a -> {c, d, e}|>, d -> Nothing, All]

<|a -> {c, e}|>

Related: Is there a difference between Replace with parameter "All" and ReplaceAll

$\endgroup$
1
$\begingroup$

You may use Query to evaluate the result of the replace in an Association. Query gives direct access to the key's value which then evaluated in Query.

Query[All, # /. d -> Nothing &]@<|a -> {c, d, e}|>
<|a -> {c, e}|>

Hope this helps.

$\endgroup$
3
$\begingroup$

For completeness sakes (I believe Coolwater's answer is best):

assoc = Association[ a → {c,d,e} ];

Query

assoc // Query[ All, ReplaceAll[ d → Nothing ] ]

(* <|a -> {c, e}|> *)

Note: This will need repeated use of All for nested associations.

DeleteCases

Before there was Nothing there was DeleteCases and the like:

assoc // DeleteCases[ #, d, Infinity ]&

(* <|a -> {c, e}|> *)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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