5

Considering an association:

<|"a" -> <|aa-> "asc", bb-> "asd", cc-> 0, ImageType -> "asd", dd-> "asd"|>|>

How can I make the inner keys strings?

  <|"a" -> <|"aa"-> "asc", "bb"-> "asd", "cc"-> 0, "ImageType" -> "asd", "dd"-> "asd"|>|>
István Zachar
  • 47,032
  • 20
  • 143
  • 291
SuTron
  • 1,708
  • 1
  • 11
  • 21

3 Answers3

5
assoc= <|"a" -> <| aa-> "asc", bb->"asd", cc->0, ImageType->"asd", dd-> "asd"|>|>;
KeyMap[ToString]/@assoc
(* <|"a" -> <|"aa" -> "asc", "bb" -> "asd", "cc" -> 0, 
   "ImageType" -> "asd", "dd" -> "asd"|>|> *)

Update:

but what if I have n levels?

I hope there is a better/cleaner way to deal with nested associations than the following:

assoc2= <| a-> <| aa-> "asc", bb->"asd", cc->0, ImageType->"asd", 
          dd-> <|dd1->"asd", dd2->"asd2"|>|>|>;

Replace[assoc2/. Association->foo, Rule[a_,b_]:>Rule[ToString[a],b],
        {0,Infinity}]/. foo->Association
(* <|"a" -> <|"aa" -> "asc", "bb" -> "asd", "cc" -> 0, 
   "ImageType" -> "asd", 
   "dd" -> <|"dd1" -> "asd", "dd2" -> "asd2"|>|>|> *)
kglr
  • 394,356
  • 18
  • 477
  • 896
4

Interestingly, not any of the association *Map (KeyMap, AssociationMap, KeyValueMap) functions accept a third argument for level specification. One can use Replace but with an extra Evaluate, as the replacement does not evaluate the KeyMap function:

ass = <|a -> <|aa -> "aa", ab -> <|ab1 -> "x", ab2 -> "y"|>|>|>;

Replace[ass, a_Association :> (Evaluate /@ KeyMap[ToString, a]), {0, Infinity}]
<|"a" -> <|"aa" -> "aa", "ab" -> <|"ab1" -> "x", "ab2" -> "y"|>|>|>

Without the forced evaluation, ToString is applied but not evaluated:

Replace[ass, a_Association :> KeyMap[ToString, a], {0, Infinity}]
 <|"a" -> KeyMap[ToString, <|aa -> "aa", 
         ab -> KeyMap[ToString, <|ab1 -> "x", ab2 -> "y"|>]|>]|>

(version 10.1, Win7 64)

István Zachar
  • 47,032
  • 20
  • 143
  • 291
  • I am not finding the Evaluate necessary; which version are you using? – Mr.Wizard Apr 12 '15 at 16:16
  • @Mr.Wizard I consistently get the unevaluated result; could this be a bug? Or am I overlooking something about the internals of associations? – István Zachar Apr 12 '15 at 16:44
  • Probably just a change in evaluation; associations and datasets are still in flux it seems. Thanks for confirming. – Mr.Wizard Apr 12 '15 at 16:45
  • @Mr.Wizard BTW, do you have any idea why these functions are not applicable at different levels? Association is not meant to be a single-level vector, even the documentation has many nested examples, so I wonder. – István Zachar Apr 12 '15 at 16:46
  • My first guess is that it simply hasn't been implemented yet. However I am curious: which parts of the documentation have nested associations rather than simply lists of associations? I cannot at the moment recall examples of the former, but I also did not search. – Mr.Wizard Apr 12 '15 at 20:57
  • @Mr.Wizard Look around Dataset, under Applications > Associations of Associations, e.g. ExampleData[{"Dataset", "Planets"}]. – István Zachar Apr 12 '15 at 21:55
  • Thanks. I forgot about that one. Nevertheless it is with in a Dataset which has its own (somewhat nascent) mechanism for manipulation. Are there any other examples? I ask not because I think this shouldn't be handled, as I really think it should, but just for reference. – Mr.Wizard Apr 12 '15 at 22:02
  • @Mr.Wizard You might be right: while there are some examples (like Associations as keys), now that I scanned the docs I do have the feeling that an association is meant to be (used mainly as...) one-dimensional. And of course, there is this, which might indicate that the 1D-approach is intentional. But on the other hand, labeled data is automatically used by charting functions as labels/legend... – István Zachar Apr 13 '15 at 16:02
2

A derivative of István's answer:

asc = <|"a" -> <|aa -> "asc" + "zzz", bb -> "asd", cc -> 0, ImageType -> "asd", 
     dd -> "asd"|>|>;
AssociateTo[asc, "foo" -> asc];

fn[a_Association] := KeyMap[ToString, a]
fn[else_] := else

fn //@ asc // InputForm
<|"a" -> <|"aa" -> "asc" + "zzz", "bb" -> "asd", "cc" -> 0,
   "ImageType" -> "asd", "dd" -> "asd"|>, 
 "foo" -> <|"a" -> <|"aa" -> "asc" + "zzz", "bb" -> "asd",
    "cc" -> 0, "ImageType" -> "asd", "dd" -> "asd"|>|>|>
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371