Pattern match for nested Association

Currently pattern - matcher doesn' t go inside an Association, and _Association is an exception (head test). You can note, for example, that an Association is AtomQ (although this is only a consequence of that). So, if you want to use pure patterns, you're currently out of luck. But, you can use recursive patterns. In this case:

nestedAssocPattern = assoc_Association /; MemberQ[Values[assoc], _Association]

Now, you can test:

MatchQ[testAssoc, nestedAssocPattern]

(* True *)

MatchQ[<|1 -> 2|>, nestedAssocPattern]

(* False *)

With 10.4 you can use KeyValuePattern, or you can do it directly with a condition.

This gives elements whose keys are Associations:

Cases[{<|a -> <|1 -> 1|>, b -> <|2 -> 2|>|>, <|a -> <|1 -> 1, 2 -> 2|>, c -> 4|>}, 
    x_Association /; Union[Head /@ Values@x] == {Association}, {1}]

(* {<|a -> <|1 -> 1|>, b -> <|2 -> 2|>|>}  *)

As already pointed out by others Association objects are presently not traversed by pattern matching.

See:

  • MatchQ-ing Associations (MMA 10)
  • difficulty abstracting the OptionValue pattern

My interpretation of your question is that you want to test to see if all values in the top Association are themselves Associations, rather than testing if only one value is, which is what kguler and Leonid answered. Therefore I propose:

asc_Association /; MatchQ[Values[asc], {__Association}]

This checks that entire expression and all of its values are Associations.


One could almost use this Condition instead of MatchQ: AllTrue[asc, AssociationQ] except that:

AllTrue[<||>, AssociationQ]
True