5
$\begingroup$

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"|>|>
$\endgroup$
1
  • 1
    $\begingroup$ Your code has syntax errors $\endgroup$
    – Nasser
    Commented Apr 12, 2015 at 13:56

3 Answers 3

5
$\begingroup$
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"|>|>|> *)
$\endgroup$
4
  • $\begingroup$ This works for 2nd level only. $\endgroup$
    – SuTron
    Commented Apr 12, 2015 at 14:26
  • $\begingroup$ @SuTron, right; but isn't that your question (How can I make the inner keys strings?) $\endgroup$
    – kglr
    Commented Apr 12, 2015 at 14:36
  • $\begingroup$ Yes, but what if I have n levels? $\endgroup$
    – SuTron
    Commented Apr 12, 2015 at 14:41
  • $\begingroup$ @SuTron, please see the update. $\endgroup$
    – kglr
    Commented Apr 12, 2015 at 14:56
4
$\begingroup$

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)

$\endgroup$
8
  • $\begingroup$ I am not finding the Evaluate necessary; which version are you using? $\endgroup$
    – Mr.Wizard
    Commented Apr 12, 2015 at 16:16
  • $\begingroup$ @Mr.Wizard I consistently get the unevaluated result; could this be a bug? Or am I overlooking something about the internals of associations? $\endgroup$ Commented Apr 12, 2015 at 16:44
  • $\begingroup$ Probably just a change in evaluation; associations and datasets are still in flux it seems. Thanks for confirming. $\endgroup$
    – Mr.Wizard
    Commented Apr 12, 2015 at 16:45
  • $\begingroup$ @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. $\endgroup$ Commented Apr 12, 2015 at 16:46
  • $\begingroup$ 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. $\endgroup$
    – Mr.Wizard
    Commented Apr 12, 2015 at 20:57
2
$\begingroup$

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"|>|>|>
$\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.