The following input:
Cases[{"key" -> Association[]}, HoldPattern["key" -> Association[]]]
Returns {}
. Why does it not return {"key" -> Association[]}
? I was expecting it to match.
Mathematica Stack Exchange is a question and answer site for users of Wolfram Mathematica. It only takes a minute to sign up.
Sign up to join this communityTo answer the question of why there is no match let's look at the output of Trace
:
Cases[{"key" -> Association[]}, HoldPattern["key" -> Association[]]] // Trace
(* {{{{Association[], <||>}, "key" -> <||>, "key" -> <||>},
{"key" -> <||>}}, Cases[{"key" -> <||>}, HoldPattern["key" -> Association[]]], {}} *)
We see that Association[]
gets evaluated to <||>
, which as Leonid states is not a normal expression and so will not match Association[]
.
As I suggested in the comments, I think the right approach in this and similar situation where an evaluation might occur with Association[]
, is to use Verbatim
:
Cases[{"key" -> Association[]}, Verbatim["key" -> Association[]]]
(* {"key" -> <||> } *)
If you look at the Trace
of the expression, you'll see why it matched.
Cases[{"key" -> Association[]}, Verbatim["key" -> Association[]]] // Trace
Verbatim
allows its input to also evaluate, hence both expressions now look the same: "key" -> <||>
, hence the match.
Finally, if for some reason you really want to use HoldPattern
, then I suggest wrapping your expression in Unevaluated
:
Cases[Unevaluated[{"key" -> Association[]}], HoldPattern["key" -> Association[]]]
(* {"key" -> <||> } *)
_ -> Association[]
(using Unevaluated
is not an option)?
$\endgroup$
Apr 19, 2016 at 17:33
Unevaluated
works for me. Cases[Unevaluated[{_ -> Association[]}], HoldPattern[_ -> Association[]]]
$\endgroup$
Apr 19, 2016 at 17:58
Verbatim
for that.HoldPattern
is for patterns $\endgroup$HoldPattern
to treat the rule itself as a pattern, otherwise the rule is interpreted byCases
(as discussed here: mathematica.stackexchange.com/questions/112333/…) $\endgroup$Association[]
evaluates to<||>
, and even though theFullForm
s of the two are the same,SameQ
on them givesFalse
, because the constructorAssociation[]
does a non-trivial job when evaluated, and the result of it is not a normal expressionAssociation[]
, but a new atomic object. So, we haveUnevaluated[Association[]] === Association[]
producingFalse
. Therefore,MatchQ[Association[], HoldPattern[Association[]]]
givesFalse
, while of courseMatchQ[Association[], HoldPattern[Evaluate@Association[]]]
givesTrue
. $\endgroup$Association
is an atomic expression. But how would you suggest I do the matching withCases
? Inspired by yourMatchQ
example I can see thatCases[{Association[]}, HoldPattern[Evaluate@Association[]]]
matches, but it won't match if the expression containingAssociation
is aRule
. For instance:Cases[{"key" -> Association[]}, HoldPattern["key" -> Evaluate@Association[]]]
won't match. $\endgroup$Verbatim
, as @RunnyKine suggested. Since it does not prevent evaluation of parts of the pattern, you will then compare evaluated / constructedAssociation[]
in your expression with a similarly evaluatedAssociation[]
inside the pattern. Or, much simpler, if you don't care whether or not association is empty, you could use_Association
pattern, which is matched in both cases. $\endgroup$