6
$\begingroup$

I'm relatively unfamiliar with associations. I wish to select association elements (i.e., keys and values) whose values are not Null or {} (i.e., an empty list). What's an elegant, efficient way to do this?

Consider an association myAssociation:

myAssociation = <|prefix -> "Dr.", firstName -> "Andrew", suffix -> Null,
   nickname -> "", aliases -> {}, streetAddress -> 1234, province -> Null,
   favoriteColors -> {"blue", "yellow"},"favoriteVegetables" -> {},
   "favoriteFruits" -> {"peaches", "plums"}|>;

I wish to return elements whose values are not Null or {}. I have found that Select -- in tandem with ==, ===, or MemberQ -- can be used to select elements with values Null or {}:

Select[myAssociation, (# == {}) || (# == Null) &]
Select[myAssociation, (# === {}) || (# === Null) &]
Select[myAssociation, MemberQ[{Null, {}}, #] &]

<|suffix -> Null, aliases -> {}, province -> Null, "favoriteVegetables" -> {}|>

<|suffix -> Null, aliases -> {}, province -> Null, "favoriteVegetables" -> {}|>

<|suffix -> Null, aliases -> {}, province -> Null, "favoriteVegetables" -> {}|>

So, to find elements without values of Null or {}, I need to simply invert the selection criteria:

Select[myAssociation, ! MemberQ[{Null, {}}, #] &]

<|prefix -> "Dr.", firstName -> "Andrew", nickname -> "", streetAddress -> 1234, favoriteColors -> {"blue", "yellow"}, "favoriteFruits" -> {"peaches", "plums"}|>

Is there an easier, more elegant, more efficient way to do this?

$\endgroup$

3 Answers 3

9
$\begingroup$

Using KeyValueMap:

KeyValueMap[If[FreeQ[Null | {}][#2], #1 -> #2, Nothing] &, myAssociation]

Or a shorter version using Select:

Select[myAssociation, FreeQ[Null | {}]]
$\endgroup$
3
$\begingroup$
myAssociation =
  <|prefix -> "Dr.", firstName -> "Andrew", suffix -> Null, 
   nickname -> "", aliases -> {}, streetAddress -> 1234, 
   province -> Null, favoriteColors -> {"blue", "yellow"}, 
   "favoriteVegetables" -> {}, 
   "favoriteFruits" -> {"peaches", "plums"}|>;

1.

We use Position to get a list of the unwanted Keys

p = First /@ Position[myAssociation, Null | {}]

{Key[suffix], Key[aliases], Key[province], Key["favoriteVegetables"]}

and use it with KeyDrop

KeyDrop[p] @ myAssociation

<|prefix -> "Dr.", firstName -> "Andrew", nickname -> "", streetAddress -> 1234, favoriteColors -> {"blue", "yellow"}, "favoriteFruits" -> {"peaches", "plums"}|>

2.

If we want to change myAssociation inline we can use KeyDropFrom

KeyDropFrom[myAssociation, p];

myAssociation

<|prefix -> "Dr.", firstName -> "Andrew", nickname -> "", streetAddress -> 1234, favoriteColors -> {"blue", "yellow"}, "favoriteFruits" -> {"peaches", "plums"}|>

$\endgroup$
3
$\begingroup$
DeleteCases[Null | {}] @ myAssociation 
<|prefix -> "Dr.",   
  firstName -> "Andrew",   
  nickname -> "",   
  streetAddress -> 1234,   
  favoriteColors -> {"blue", "yellow"},   
  "favoriteFruits" -> {"peaches", "plums"}|>
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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