7
$\begingroup$

Consider the following association of associations:

assoc = <|
  {10,69}-><|84->1,88->2,110->1,118->4,108->1,114->8,78->2,112->1|>,
  {69,84}-><|89->1,79->1,85->1,46->4,73->5,84->5,32->10,72->4,44->2,67->1,65->1,39->1,76->1,87->1|>,
  {84,89}-><|77->1,69->1,32->1,46->1|>,
  {89,77}-><|79->1|>,
  {77,79}-><|76->1,82->8,85->5,78->4,68->1,32->1,44->2,41->4,69->1,86->2,75->1|>
  {79,76}-><|79->3,76->8,89->1,68->8,65->3,78->1,69->1,73->10,85->1,83->1|>,
  {76,79}-><|71->3,45->1,82->34,83->2,66->4,65->1,67->2,78->7,79->3,84->1,85->1,87->7|>,
  {79,71}-><|89->3,82->2|>,
  {71,89}-><|46->2,32->1|>,
  {89,46}-><|10->8,34->1,41->1|>
|>

Why does Cases[Length /@ assoc // Normal, (key_List -> val_) :> key /; val == 1] work (it returns {{89, 77}}) while Cases[Length /@ assoc, (key_List -> val_) :> key /; val == 1] doesn't?

$\endgroup$
9
$\begingroup$

Cases has been overloaded for Association. Consider this example,

Cases[<|1 -> a, 2 -> "b", 3 -> "c"|>, _String]
(* {"b", "c"} *)

The keys are lost here, and so the RuleDelayed has no effect. However, Select returns an Association, even though it applies the predicate only to the values,

Select[<|1 -> a, 2 -> "b", 3 -> "c"|>, StringQ]
(* <|2 -> "b", 3 -> "c"|> *)

For the example in the OP, we can use Select, and then use Keys on the result,

Keys@Select[assoc, Length[#] == 1 &]
(* {{89, 77}} *)

edit:

You might think that KeyValuePattern is the right way to go here, but be aware that Cases is still going to match it only to the values:

Cases[assoc, 
 KeyValuePattern[key_ -> x_ /; Length[x] == 1] :> key]
(* {} *)

A workaround for this would be to wrap the Association in a List,

Cases[{assoc}, 
 KeyValuePattern[key_ -> x_ /; Length[x] == 1] :> key]
(* {{89, 77}} *)

I think it would be useful to have a KeyValueCases for something like this.

$\endgroup$
  • $\begingroup$ It was exactly my failure to work something out using KeyValuePattern that prompted this question; thanks $\endgroup$ – user42582 Jan 15 '18 at 18:27

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.