# MatchQ-ing Associations (MMA 10)

Consider

{x->1}


which has FullForm

List[Rule[x, 1]]


and, therefore,

MatchQ[{x->1}, List[___Rule]]


produces True.

Now consider

<|x->1|>


which has FullForm

Association[Rule[x, 1]]


but

MatchQ[<|x->1|>, Association[___Rule]]


produces False

In fact,

MatchQ[<|x->1|>, Association[___]]


produces False. Any ideas? (I'm trying to make some MathLink xxxxxxxx WSTP functions for serializing C structs as Associations, and this lacuna is messing me up).

• MatchQ[ Normal @ <|x->1|>, Normal @ Association[ x -> _ ] or MatchQ[ Normal @ <|x->1|>, List[ ___ Rule] ] will work though. – gwr Sep 26 '15 at 14:16

Association is atomic:

<|x -> 1|> // AtomQ

True


Therefore standard pattern matching inside the structure will not work.

You can still match on the implicit head using:

MatchQ[<|x -> 1|>, _Association]

True


There is also AssociationQ:

<|x -> 1|> // AssociationQ

True

MatchQ[<|x -> 1|>, _?AssociationQ]

True


I used the term atomic in a general way meaning an object that does not conform to the standard expression syntax and traversal rules. Taliesin Beynon explains why this is conflating two different concepts in this chat transcript.

• It just so happens that Association is currently AtomQ, though I've argued strongly against that fact internally, and I've got SW's say-so that we'll change that eventually. But that doesn't have all that much to do with pattern matching not working inside associations: we all agree it should, it's just hard to do efficiently and we couldn't deliver it for 10. So, to sum up: Association will not be AtomQ forever, and it will support pattern matching eventually. There's a correlation here, not a causation. – Taliesin Beynon Jul 22 '14 at 5:33
• @Taliesin Thanks for the clarification, however I'm afraid I don't understand it. If Assocation objects were standard Mathematica expressions then pattern matching would work by default, would it not? I realize pattern matching could be overloaded for an Atomic object as I believe it is for Complex, but I still think there is causation here. Am I mistaken? – Mr.Wizard Jul 22 '14 at 5:40
• I can see that pattern-matching over the contents of an Association would be difficult. Thanks for the info! – Reb.Cabin Jul 22 '14 at 12:18
• A possibly similar problem arises, for instance, in deciding whether the two JSON objects {a: 1, b: 2} and {b: 2, a: 1} are equal; the problem explodes with size, requiring either some arbitrary sort on the keys or considering $n!$ possibilities (modulo nesting). – Reb.Cabin Jul 22 '14 at 12:25
• @Reb.Cabin, since the sorting is arbitrary can't the data be normalized internally? eg like FullForm[x + 1] == FullForm[1 + x] = Plus[1,x] – alancalvitti Jul 22 '14 at 14:07

In Mathematica 10.4, Association can now be used in pattern matching. Here is the result of the OP's example:

MatchQ[<|x -> 1|>, Association[___Rule]]


True

and

MatchQ[<|x->1|>, Association[___]]


True

There's now also KeyValuePattern which is a pattern object specifically to match elements of an Association or list of rules. Here are some examples:

<|a -> 1, b -> 2, c -> 3|> /. KeyValuePattern[x_ -> 1] :> x


a

Cases[{
<|"PartOfSpeech" -> "Noun", "Number" -> "Singular"|>,
<|"PartOfSpeech" -> "Verb"|>},
KeyValuePattern[{x : "PartOfSpeech" -> y : "Noun"}] :>
Association[x -> y]]


{<|"PartOfSpeech" -> "Noun"|>}